/*---------------------------------------------------------------------------*\
========= |
\\ / 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();
}
}
// ************************************************************************* //