diff --git a/applications/test/DynamicField/DynamicFieldTest.C b/applications/test/DynamicField/DynamicFieldTest.C index bfff5b2453d0c644e2815c4361225f93efb85655..1a7ccb463bc4dea8d7aef188d5b10f3a0ce8351e 100644 --- a/applications/test/DynamicField/DynamicFieldTest.C +++ b/applications/test/DynamicField/DynamicFieldTest.C @@ -2,16 +2,16 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd. + \\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd. \\/ 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 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 2 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 @@ -19,15 +19,16 @@ License for more details. You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Description \*---------------------------------------------------------------------------*/ +#include "point.H" #include "DynamicField.H" #include "IOstreams.H" -#include "labelField.H" using namespace Foam; @@ -36,44 +37,62 @@ using namespace Foam; int main(int argc, char *argv[]) { - { - DynamicField<label> dl(10); - Pout<< "null construct dl:" << dl << endl; - dl.append(3); - dl.append(2); - dl.append(1); - Pout<< "appending : dl:" << dl << endl; - - dl[2] *= 10; - Pout<< "assigning : dl:" << dl << endl; - } - - { - DynamicField<label> dl(IStringStream("(1 2 3)")()); - Pout<< "reading : dl:" << dl << endl; - } - - { - labelField lf(3); - lf[0] = 1; - lf[1] = 2; - lf[2] = 3; - DynamicField<label> dl; - dl = lf; - Pout<< "assigning from labelField : dl:" << dl << endl; - } - - { - labelField lf(3); - lf[0] = 1; - lf[1] = 2; - lf[2] = 3; - DynamicField<label> dl(lf); - Pout<< "constructing from labelField dl:" << dl << endl; - } - - - Info<< "\nEnd\n"; + DynamicField<point, 0, 10, 11> testField; + DynamicField<point, 0, 10, 11> testField2; + + testField.setSize(5); + testField2.setSize(5); + + testField[0] = testField2[0] = vector(1.0, 4.5, 6.3); + testField[1] = testField2[1] = vector(5.2, 2.3, 3.5); + testField[2] = testField2[2] = vector(7.5, 4.7, 7.7); + testField[3] = testField2[3] = vector(2.8, 8.2, 2.3); + testField[4] = testField2[4] = vector(6.1, 1.7, 8.8); + + Info << "testField:" << testField << endl; + + testField.append(vector(0.5, 4.8, 6.2)); + + Info << "testField after appending:" << testField << endl; + + testField.append(vector(2.7, 2.3, 6.1)); + + Info << "testField after appending:" << testField << endl; + + vector elem = testField.remove(); + + Info << "removed element:" << elem << endl; + Info << "testField:" << testField << endl; + + testField.append(vector(3.0, 1.3, 9.2)); + + Info << "testField:" << testField << endl; + + testField.setSize(10, vector(1.5, 0.6, -1.0)); + + Info << "testField after setSize:" << testField << endl; + + testField.append(testField2); + + Info << "testField after appending testField2:" << testField << endl; + + testField = testField2; + + Info << "testField after assignment:" << testField << endl; + + testField += testField2; + + Info << "testField after field algebra:" << testField << endl; + + testField.clear(); + + testField.append(vector(3.0, 1.3, 9.2)); + + Info << "testField after clear and append:" << testField << endl; + + testField.clearStorage(); + + Info << "testField after clearStorage:" << testField << endl; return 0; } diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.C b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.C index f557f1f43c80d8967124ace7fb7d4c4ab132f637..d01ce9bb5b1f818e77e5a0813c48f099582884dc 100644 --- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.C +++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.C @@ -25,87 +25,53 @@ License #include "DynamicField.H" -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // -namespace Foam -{ - -// * * * * * * * * * * * * * * * Static Members * * * * * * * * * * * * * * // - -template<class Type> -const char* const DynamicField<Type>::typeName("DynamicField"); - - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -template<class Type> -DynamicField<Type>::DynamicField(Istream& is) +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField(Istream& is) : - Field<Type>(is), - capacity_(Field<Type>::size()) + Field<T>(is), + capacity_(Field<T>::size()) {} -template<class Type> -tmp<DynamicField<Type> > DynamicField<Type>::clone() const +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +Foam::tmp<Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv> > +Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::clone() const { - return tmp<DynamicField<Type> >(new DynamicField<Type>(*this)); + return tmp<DynamicField<T, SizeInc, SizeMult, SizeDiv> > + ( + new DynamicField<T, SizeInc, SizeMult, SizeDiv>(*this) + ); } -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -template<class Type> -void DynamicField<Type>::setSize(const label nElem) -{ - // allocate more capacity? - if (nElem > capacity_) - { - capacity_ = max(nElem, label(1 + capacity_*2)); - - Field<Type>::setSize(capacity_); - } - - // adjust addressed size - Field<Type>::size(nElem); -} - - -// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // - - // * * * * * * * * * * * * * * * IOstream Operator * * * * * * * * * * * * * // -template<class Type> -Ostream& operator<<(Ostream& os, const DynamicField<Type>& f) +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +Foam::Ostream& Foam::operator<< +( + Ostream& os, + const DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst +) { - os << static_cast<const Field<Type>&>(f); + os << static_cast<const Field<T>&>(lst); return os; } -template<class Type> -Ostream& operator<<(Ostream& os, const tmp<DynamicField<Type> >& tf) +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +Foam::Istream& Foam::operator>> +( + Istream& is, + DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst +) { - os << tf(); - tf.clear(); - return os; -} - - -template<class Type> -Istream& operator>>(Istream& is, DynamicField<Type>& lst) -{ - is >> static_cast<Field<Type>&>(lst); - lst.capacity_ = lst.Field<Type>::size(); + is >> static_cast<Field<T>&>(lst); + lst.capacity_ = lst.Field<T>::size(); return is; } -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - - // ************************************************************************* // diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H index a464ac9d2243ca7dab8128e3ca8b5f0e0d3df0ff..d05d2f5d84b2f448061a85dab738f47428d0346b 100644 --- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H +++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H @@ -25,9 +25,10 @@ Class Foam::DynamicField Description - Dynamically sized Field. WIP. + Dynamically sized Field. SourceFiles + DynamicFieldI.H DynamicField.C \*---------------------------------------------------------------------------*/ @@ -44,89 +45,78 @@ namespace Foam // Forward declaration of friend functions and operators -template<class Type> +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> class DynamicField; -template<class Type> -Ostream& operator<<(Ostream&, const DynamicField<Type>&); - -template<class Type> -Ostream& operator<<(Ostream&, const tmp<DynamicField<Type> >&); - -template<class Type> -Istream& operator>>(Istream&, DynamicField<Type>&); +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +Ostream& operator<< +( + Ostream&, + const DynamicField<T, SizeInc, SizeMult, SizeDiv>& +); +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +Istream& operator>> +( + Istream&, + DynamicField<T, SizeInc, SizeMult, SizeDiv>& +); /*---------------------------------------------------------------------------*\ Class DynamicField Declaration \*---------------------------------------------------------------------------*/ -template<class Type> +template<class T, unsigned SizeInc=0, unsigned SizeMult=2, unsigned SizeDiv=1> class DynamicField : - public Field<Type> + public Field<T> { - // Private data //- The capacity (allocated size) of the underlying field. label capacity_; - //- Construct given size and initial value - DynamicField(const label, const Type&); - - //- Construct as copy of tmp<DynamicField> -# ifdef ConstructFromTmp - DynamicField(const tmp<DynamicField<Type> >&); -# endif - - //- Construct from a dictionary entry - DynamicField(const word&, const dictionary&, const label); - public: - // Static data members - - static const char* const typeName; - - // Static Member Functions //- Return a null field - inline static const DynamicField<Type>& null() + inline static const DynamicField<T, SizeInc, SizeMult, SizeDiv>& null() { - return *reinterpret_cast< DynamicField<Type>* >(0); + return *reinterpret_cast + < + DynamicField<T, SizeInc, SizeMult, SizeDiv>* + >(0); } // Constructors //- Construct null - // Used for temporary fields which are initialised after construction - DynamicField(); + inline DynamicField(); - //- Construct given size - // Used for temporary fields which are initialised after construction + //- Construct given size. explicit inline DynamicField(const label); - //- Construct as copy of a UList\<Type\> - explicit inline DynamicField(const UList<Type>&); + //- Construct from UList. Size set to UList size. + // Also constructs from DynamicField with different sizing parameters. + explicit inline DynamicField(const UList<T>&); - //- Construct by transferring the List contents - explicit inline DynamicField(const Xfer<List<Type> >&); + //- Construct by transferring the parameter contents + explicit inline DynamicField(const Xfer<List<T> >&); //- Construct by 1 to 1 mapping from the given field inline DynamicField ( - const UList<Type>& mapF, + const UList<T>& mapF, const labelList& mapAddressing ); //- Construct by interpolative mapping from the given field inline DynamicField ( - const UList<Type>& mapF, + const UList<T>& mapF, const labelListList& mapAddressing, const scalarListList& weights ); @@ -134,59 +124,129 @@ public: //- Construct by mapping from the given field inline DynamicField ( - const UList<Type>& mapF, + const UList<T>& mapF, const FieldMapper& map ); - //- Construct as copy - inline DynamicField(const DynamicField<Type>&); - - //- Construct as copy or re-use as specified. - inline DynamicField(DynamicField<Type>&, bool reUse); + //- Construct copy + inline DynamicField(const DynamicField<T, SizeInc, SizeMult, SizeDiv>&); //- Construct by transferring the Field contents - inline DynamicField(const Xfer<DynamicField<Type> >&); + inline DynamicField + ( + const Xfer<DynamicField<T, SizeInc, SizeMult, SizeDiv> >& + ); - //- Construct from Istream - inline DynamicField(Istream&); + //- Construct from Istream. Size set to size of list read. + explicit DynamicField(Istream&); //- Clone - tmp<DynamicField<Type> > clone() const; + tmp<DynamicField<T, SizeInc, SizeMult, SizeDiv> > clone() const; // Member Functions - //- Size of the underlying storage. - inline label capacity() const; + // Access + + //- Size of the underlying storage. + inline label capacity() const; + + // Edit + + //- Alter the size of the underlying storage. + // The addressed size will be truncated if needed to fit, but will + // remain otherwise untouched. + // Use this or reserve() in combination with append(). + inline void setCapacity(const label); + + //- Alter the addressed list size. + // New space will be allocated if required. + // Use this to resize the list prior to using the operator[] for + // setting values (as per List usage). + inline void setSize(const label); + + //- Alter the addressed list size and fill new space with a + // constant. + inline void setSize(const label, const T&); + + //- Alter the addressed list size. + // New space will be allocated if required. + // Use this to resize the list prior to using the operator[] for + // setting values (as per List usage). + inline void resize(const label); + + //- Alter the addressed list size and fill new space with a + // constant. + inline void resize(const label, const T&); + + //- Reserve allocation space for at least this size. + // Never shrinks the allocated size, use setCapacity() for that. + inline void reserve(const label); + + //- Clear the addressed list, i.e. set the size to zero. + // Allocated size does not change + inline void clear(); + + //- Clear the list and delete storage. + inline void clearStorage(); + + //- Shrink the allocated space to the number of elements used. + // Returns a reference to the DynamicField. + inline DynamicField<T, SizeInc, SizeMult, SizeDiv>& shrink(); + + //- Transfer contents to the Xfer container as a plain List + inline Xfer<List<T> > xfer(); + + + // Member Operators + + //- Append an element at the end of the list + inline DynamicField<T, SizeInc, SizeMult, SizeDiv>& append + ( + const T& + ); + + //- Append a List at the end of this list + inline DynamicField<T, SizeInc, SizeMult, SizeDiv>& append + ( + const UList<T>& + ); - //- Append an element at the end of the list - inline void append(const Type&); + //- Remove and return the top element + inline T remove(); - //- Alter the addressed list size. - // New space will be allocated if required. - // Use this to resize the list prior to using the operator[] for - // setting values (as per List usage). - void setSize(const label nElem); + //- Return non-const access to an element, resizing list if + // necessary + inline T& operator()(const label); - // Member operators + //- Assignment of all addressed entries to the given value + inline void operator=(const T&); - inline void operator=(const DynamicField<Type>&); - inline void operator=(const UList<Type>&); - inline void operator=(const tmp<DynamicField<Type> >&); + //- Assignment from DynamicField + inline void operator= + ( + const DynamicField<T, SizeInc, SizeMult, SizeDiv>& + ); - //- Return element of Field. - using Field<Type>::operator[]; + //- Assignment from UList + inline void operator=(const UList<T>&); - // IOstream operators - friend Ostream& operator<< <Type> - (Ostream&, const DynamicField<Type>&); + // IOstream operators - friend Ostream& operator<< <Type> - (Ostream&, const tmp<DynamicField<Type> >&); + // Write DynamicField to Ostream. + friend Ostream& operator<< <T, SizeInc, SizeMult, SizeDiv> + ( + Ostream&, + const DynamicField<T, SizeInc, SizeMult, SizeDiv>& + ); - friend Istream& operator>> <Type> - (Istream&, DynamicField<Type>&); + //- Read from Istream, discarding contents of existing DynamicField. + friend Istream& operator>> <T, SizeInc, SizeMult, SizeDiv> + ( + Istream&, + DynamicField<T, SizeInc, SizeMult, SizeDiv>& + ); }; diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H b/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H index bc54c71fbd07242671b3ca68ce383421c42a04b3..588ca07440d26b7b95b06d2891e7fbd58e7680ac 100644 --- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H +++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H @@ -23,175 +23,441 @@ License \*---------------------------------------------------------------------------*/ -#include "DynamicField.H" - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -template<class Type> -Foam::DynamicField<Type>::DynamicField() +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField() : - Field<Type>(), - capacity_(0) + Field<T>(0), + capacity_(Field<T>::size()) {} -template<class Type> -Foam::DynamicField<Type>::DynamicField(const label size) +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField +( + const label nElem +) : - Field<Type>(size), - capacity_(Field<Type>::size()) + Field<T>(nElem), + capacity_(Field<T>::size()) { - Field<Type>::size(0); + // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv) + Field<T>::size(0); } -template<class Type> -inline Foam::DynamicField<Type>::DynamicField +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField ( - const UList<Type>& lst + const UList<T>& lst ) : - Field<Type>(lst), - capacity_(Field<Type>::size()) + Field<T>(lst), + capacity_(Field<T>::size()) {} -template<class Type> -inline Foam::DynamicField<Type>::DynamicField +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField ( - const Xfer<List<Type> >& lst + const Xfer<List<T> >& lst ) : - Field<Type>(lst), - capacity_(Field<Type>::size()) + Field<T>(lst), + capacity_(Field<T>::size()) {} -template<class Type> -Foam::DynamicField<Type>::DynamicField +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField ( - const UList<Type>& mapF, + const UList<T>& mapF, const labelList& mapAddressing ) : - Field<Type>(mapF, mapAddressing), - capacity_(Field<Type>::size()) + Field<T>(mapF, mapAddressing), + capacity_(Field<T>::size()) {} -template<class Type> -Foam::DynamicField<Type>::DynamicField +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField ( - const UList<Type>& mapF, + const UList<T>& mapF, const labelListList& mapAddressing, const scalarListList& weights ) : - Field<Type>(mapF, mapAddressing, weights), - capacity_(Field<Type>::size()) + Field<T>(mapF, mapAddressing, weights), + capacity_(Field<T>::size()) {} //- Construct by mapping from the given field -template<class Type> -Foam::DynamicField<Type>::DynamicField +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField ( - const UList<Type>& mapF, + const UList<T>& mapF, const FieldMapper& map ) : - DynamicField<Type>(mapF, map), - capacity_(Field<Type>::size()) -{} - - -template<class Type> -Foam::DynamicField<Type>::DynamicField(const DynamicField<Type>& f) -: - Field<Type>(f), - capacity_(Field<Type>::size()) + Field<T>(mapF, map), + capacity_(Field<T>::size()) {} -template<class Type> -Foam::DynamicField<Type>::DynamicField(DynamicField<Type>& f, bool reUse) +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField +( + const DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst +) : - Field<Type>(f, reUse), - capacity_(Field<Type>::size()) + Field<T>(lst), + capacity_(lst.capacity()) {} -template<class Type> -Foam::DynamicField<Type>::DynamicField(const Xfer<DynamicField<Type> >& f) +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField +( + const Xfer<DynamicField<T, SizeInc, SizeMult, SizeDiv> >& lst +) : - Field<Type>(f), - capacity_(Field<Type>::size()) + Field<T>(lst), + capacity_(Field<T>::size()) {} // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -template<class Type> -Foam::label Foam::DynamicField<Type>::capacity() const +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline Foam::label Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::capacity() +const { return capacity_; } -template<class Type> -void Foam::DynamicField<Type>::append(const Type& t) +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::setCapacity +( + const label nElem +) +{ + label nextFree = Field<T>::size(); + capacity_ = nElem; + + if (nextFree > capacity_) + { + // truncate addressed sizes too + nextFree = capacity_; + } + // we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv) + + Field<T>::setSize(capacity_); + Field<T>::size(nextFree); +} + + +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::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<T>::size(); + Field<T>::setSize(capacity_); + Field<T>::size(nextFree); + } +} + + +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::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<T>::setSize(capacity_); + } + + // adjust addressed size + Field<T>::size(nElem); +} + + +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::setSize +( + const label nElem, + const T& t +) +{ + label nextFree = Field<T>::size(); + setSize(nElem); + + // set new elements to constant value + while (nextFree < nElem) + { + this->operator[](nextFree++) = t; + } +} + + +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::resize +( + const label nElem +) +{ + this->setSize(nElem); +} + + +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::resize +( + const label nElem, + const T& t +) +{ + this->setSize(nElem, t); +} + + +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::clear() +{ + Field<T>::size(0); +} + + +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::clearStorage() +{ + Field<T>::clear(); + capacity_ = 0; +} + + +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>& +Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::shrink() +{ + label nextFree = Field<T>::size(); + if (capacity_ > nextFree) + { + // use the full list when resizing + Field<T>::size(capacity_); + + // the new size + capacity_ = nextFree; + Field<T>::setSize(capacity_); + Field<T>::size(nextFree); + } + return *this; +} + + +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline Foam::Xfer<Foam::List<T> > +Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::xfer() { - label elemI = Field<Type>::size(); + return xferMoveTo< List<T> >(*this); +} + + +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>& +Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::append +( + const T& t +) +{ + const label elemI = List<T>::size(); setSize(elemI + 1); this->operator[](elemI) = t; + return *this; +} + + +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>& +Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::append +( + const UList<T>& lst +) +{ + if (this == &lst) + { + FatalErrorIn + ( + "DynamicField<T, SizeInc, SizeMult, SizeDiv>::append" + "(const UList<T>&)" + ) << "attempted appending to self" << abort(FatalError); + } + + label nextFree = List<T>::size(); + setSize(nextFree + lst.size()); + + forAll(lst, elemI) + { + this->operator[](nextFree++) = lst[elemI]; + } + return *this; +} + + +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline T Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::remove() +{ + const label elemI = List<T>::size() - 1; + + if (elemI < 0) + { + FatalErrorIn + ( + "Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::remove()" + ) << "List is empty" << abort(FatalError); + } + + const T& val = List<T>::operator[](elemI); + + List<T>::size(elemI); + + return val; } // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // -template<class Type> -void Foam::DynamicField<Type>::operator=(const DynamicField<Type>& rhs) +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline T& Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator() +( + const label elemI +) { - if (this == &rhs) + if (elemI >= Field<T>::size()) { - FatalErrorIn("DynamicField<Type>::operator=(const DynamicField<Type>&)") - << "attempted assignment to self" - << abort(FatalError); + setSize(elemI + 1); } - Field<Type>::operator=(rhs); - capacity_ = Field<Type>::size(); + return this->operator[](elemI); } -template<class Type> -void Foam::DynamicField<Type>::operator=(const UList<Type>& rhs) +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator= +( + const T& t +) { - Field<Type>::operator=(rhs); - capacity_ = Field<Type>::size(); + UList<T>::operator=(t); } -template<class Type> -void Foam::DynamicField<Type>::operator=(const tmp<DynamicField>& rhs) +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator= +( + const DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst +) { - if (this == &(rhs())) + if (this == &lst) + { + FatalErrorIn + ( + "DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=" + "(const DynamicField<T, SizeInc, SizeMult, SizeDiv>&)" + ) << "attempted assignment to self" << abort(FatalError); + } + + if (capacity_ >= lst.size()) { - FatalErrorIn("DynamicField<Type>::operator=(const tmp<DynamicField>&)") - << "attempted assignment to self" - << abort(FatalError); + // can copy w/o reallocating, match initial size to avoid reallocation + Field<T>::size(lst.size()); + Field<T>::operator=(lst); } + else + { + // make everything available for the copy operation + Field<T>::size(capacity_); - // This is dodgy stuff, don't try it at home. - DynamicField* fieldPtr = rhs.ptr(); - List<Type>::transfer(*fieldPtr); - delete fieldPtr; - capacity_ = Field<Type>::size(); + Field<T>::operator=(lst); + capacity_ = Field<T>::size(); + } } -// * * * * * * * * * * * * * * * IOstream Operator * * * * * * * * * * * * * // +template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> +inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator= +( + const UList<T>& lst +) +{ + if (capacity_ >= lst.size()) + { + // can copy w/o reallocating, match initial size to avoid reallocation + Field<T>::size(lst.size()); + Field<T>::operator=(lst); + } + else + { + // make everything available for the copy operation + Field<T>::size(capacity_); + + Field<T>::operator=(lst); + capacity_ = Field<T>::size(); + } +} // ************************************************************************* //