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