/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- 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 . \*---------------------------------------------------------------------------*/ // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template inline Foam::DynamicField::DynamicField() : Field(0), capacity_(Field::size()) {} template inline Foam::DynamicField::DynamicField ( const label nElem ) : Field(nElem), capacity_(Field::size()) { // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv) Field::size(0); } template inline Foam::DynamicField::DynamicField ( const UList& lst ) : Field(lst), capacity_(Field::size()) {} template inline Foam::DynamicField::DynamicField ( const Xfer>& lst ) : Field(lst), capacity_(Field::size()) {} template inline Foam::DynamicField::DynamicField ( const UList& mapF, const labelList& 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()) {} template inline Foam::DynamicField::DynamicField ( const DynamicField& lst ) : Field(lst), capacity_(lst.capacity()) {} template inline Foam::DynamicField::DynamicField ( const Xfer>& lst ) : Field(lst), capacity_(Field::size()) {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template inline Foam::label Foam::DynamicField::capacity() const { 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 SizeInc granularity when (!SizeMult || !SizeDiv) Field::setSize(capacity_); Field::size(nextFree); } template inline void Foam::DynamicField::reserve ( const label nElem ) { // allocate more capacity? if (nElem > capacity_) { // TODO: convince the compiler that division by zero does not occur // if (SizeInc && (!SizeMult || !SizeDiv)) // { // // resize with SizeInc as the granularity // capacity_ = nElem; // unsigned pad = SizeInc - (capacity_ % SizeInc); // if (pad != SizeInc) // { // capacity_ += pad; // } // } // else { capacity_ = max ( nElem, label(SizeInc + capacity_ * SizeMult / SizeDiv) ); } // adjust allocated size, leave addressed size untouched label nextFree = Field::size(); Field::setSize(capacity_); Field::size(nextFree); } } template inline void Foam::DynamicField::setSize ( const label nElem ) { // allocate more capacity? if (nElem > capacity_) { // TODO: convince the compiler that division by zero does not occur // if (SizeInc && (!SizeMult || !SizeDiv)) // { // // resize with SizeInc as the granularity // capacity_ = nElem; // unsigned pad = SizeInc - (capacity_ % SizeInc); // if (pad != SizeInc) // { // capacity_ += pad; // } // } // else { capacity_ = max ( nElem, label(SizeInc + capacity_ * SizeMult / SizeDiv) ); } Field::setSize(capacity_); } // adjust addressed size Field::size(nElem); } template inline void Foam::DynamicField::setSize ( const label nElem, const T& t ) { label nextFree = Field::size(); setSize(nElem); // set new elements to constant value while (nextFree < nElem) { this->operator[](nextFree++) = t; } } template inline void Foam::DynamicField::resize ( const label nElem ) { this->setSize(nElem); } template inline void Foam::DynamicField::resize ( const label nElem, const T& t ) { this->setSize(nElem, t); } template inline void Foam::DynamicField::clear() { Field::size(0); } template inline void Foam::DynamicField::clearStorage() { Field::clear(); capacity_ = 0; } 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 inline Foam::Xfer> Foam::DynamicField::xfer() { return xferMoveTo>(*this); } template inline Foam::DynamicField& Foam::DynamicField::append ( const T& t ) { const label elemI = List::size(); setSize(elemI + 1); this->operator[](elemI) = t; return *this; } template inline Foam::DynamicField& Foam::DynamicField::append ( const UList& lst ) { if (this == &lst) { FatalErrorInFunction << "attempted appending to self" << abort(FatalError); } label nextFree = List::size(); setSize(nextFree + lst.size()); forAll(lst, elemI) { this->operator[](nextFree++) = lst[elemI]; } return *this; } template inline T Foam::DynamicField::remove() { const label elemI = List::size() - 1; if (elemI < 0) { FatalErrorInFunction << "List is empty" << abort(FatalError); } const T& val = List::operator[](elemI); List::size(elemI); return val; } // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template inline T& Foam::DynamicField::operator() ( const label elemI ) { if (elemI >= Field::size()) { setSize(elemI + 1); } return this->operator[](elemI); } template inline void Foam::DynamicField::operator= ( const T& t ) { UList::operator=(t); } template inline void Foam::DynamicField::operator= ( const DynamicField& lst ) { if (this == &lst) { FatalErrorInFunction << "attempted assignment to self" << abort(FatalError); } if (capacity_ >= lst.size()) { // can copy w/o reallocating, match initial size to avoid reallocation Field::size(lst.size()); Field::operator=(lst); } else { // make everything available for the copy operation Field::size(capacity_); Field::operator=(lst); capacity_ = Field::size(); } } template inline void Foam::DynamicField::operator= ( const UList& lst ) { if (capacity_ >= lst.size()) { // can copy w/o reallocating, match initial size to avoid reallocation Field::size(lst.size()); Field::operator=(lst); } else { // make everything available for the copy operation Field::size(capacity_); Field::operator=(lst); capacity_ = Field::size(); } } // ************************************************************************* //