diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.C b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.C index a18d76fc9eba32b4f30d61bf43361ceeefcbc1dd..8598b3c1f65955dc56ac3131653156759a670eb3 100644 --- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.C +++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.C @@ -39,10 +39,7 @@ template<class T, int SizeMin> Foam::tmp<Foam::DynamicField<T, SizeMin>> Foam::DynamicField<T, SizeMin>::clone() const { - return tmp<DynamicField<T, SizeMin>> - ( - new DynamicField<T, SizeMin>(*this) - ); + return tmp<DynamicField<T, SizeMin>>::New(*this); } diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H index 80e7455006bebb9f927ffe959a27a1666c313b7f..18559ad7b64866141e76a581b906d3f87003dc9e 100644 --- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H +++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H @@ -51,20 +51,20 @@ template<class T, int SizeMin> class DynamicField; template<class T, int SizeMin> Ostream& operator<< ( - Ostream&, - const DynamicField<T, SizeMin>& + Ostream& os, + const DynamicField<T, SizeMin>& fld ); template<class T, int SizeMin> Istream& operator>> ( - Istream&, - DynamicField<T, SizeMin>& + Istream& is, + DynamicField<T, SizeMin>& fld ); /*---------------------------------------------------------------------------*\ - Class DynamicField Declaration + Class DynamicField Declaration \*---------------------------------------------------------------------------*/ template<class T, int SizeMin=64> @@ -84,7 +84,7 @@ class DynamicField //- Copy assignment from another list template<class ListType> - inline void assignDynField(const ListType& lst); + inline void assignDynField(const ListType& list); public: @@ -102,15 +102,25 @@ public: //- Construct null inline constexpr DynamicField() noexcept; - //- Construct with given capacity. + //- Construct empty field with given reserve size. explicit inline DynamicField(const label len); + //- Construct given size and initial value + inline DynamicField(const label len, const T& val); + + //- Construct given size and initial value of zero + inline DynamicField(const label len, const zero); + //- Copy construct - inline DynamicField(const DynamicField<T, SizeMin>& lst); + inline DynamicField(const DynamicField<T, SizeMin>& list); + + //- Copy construct with different sizing parameters + template<int AnySizeMin> + inline DynamicField(const DynamicField<T, AnySizeMin>& list); //- Copy construct from UList. Size set to UList size. // Also constructs from DynamicField with different sizing parameters. - explicit inline DynamicField(const UList<T>& lst); + explicit inline DynamicField(const UList<T>& list); //- Copy construct from UIndirectList explicit inline DynamicField(const UIndirectList<T>& list); @@ -118,9 +128,13 @@ public: //- Move construct from List contents explicit inline DynamicField(List<T>&& content); - //- Move construct from Field contents + //- Move construct from dynamic Field contents inline DynamicField(DynamicField<T, SizeMin>&& content); + //- Move construct with different sizing parameters + template<int AnySizeMin> + inline DynamicField(DynamicField<T, AnySizeMin>&& content); + //- Construct by 1 to 1 mapping from the given field inline DynamicField ( @@ -152,87 +166,108 @@ public: // Member Functions - // Access + // 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 nElem); + + //- 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 nElem); + + //- Alter the addressed list size and fill new space with a constant. + inline void setSize(const label nElem, const T& val); + + //- 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 nElem); + + //- Alter the addressed list size and fill new space with a + // constant. + inline void resize(const label nElem, const T& val); + + //- Reserve allocation space for at least this size. + // Never shrinks the allocated size, use setCapacity() for that. + inline void reserve(const label nElem); - //- Size of the underlying storage. - inline label capacity() const; + //- Clear the addressed list, i.e. set the size to zero. + // Allocated size does not change + inline void clear(); - // Edit + //- Clear the list and delete storage. + inline void clearStorage(); - //- 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 nElem); + //- Expand the addressable size to fit the allocated capacity. + // Returns the previous addressable size. + inline label expandStorage(); - //- 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 nElem); + //- Shrink the allocated space to the number of elements used. + // Returns a reference to the DynamicField. + inline DynamicField<T, SizeMin>& shrink(); - //- Alter the addressed list size and fill new space with a - // constant. - inline void setSize(const label nElem, const T& val); + //- Swap content with any sized DynamicField + template<int AnySizeMin> + inline void swap(DynamicField<T, AnySizeMin>& list); - //- 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 nElem); + //- Transfer the parameter contents into this + inline void transfer(List<T>& list); - //- Alter the addressed list size and fill new space with a - // constant. - inline void resize(const label nElem, const T& val); + //- Transfer the parameter contents into this + template<int AnySizeMin> + inline void transfer(DynamicList<T, AnySizeMin>& list); - //- Reserve allocation space for at least this size. - // Never shrinks the allocated size, use setCapacity() for that. - inline void reserve(const label nElem); + //- Transfer the parameter contents into this + template<int AnySizeMin> + inline void transfer(DynamicField<T, AnySizeMin>& list); - //- 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(); + //- Append an element at the end of the list + inline DynamicField<T, SizeMin>& + append(const T& val); - //- Expand the addressable size to fit the allocated capacity. - // Returns the previous addressable size. - inline label expandStorage(); + //- Append a List at the end of this list + inline DynamicField<T, SizeMin>& + append(const UList<T>& list); - //- Shrink the allocated space to the number of elements used. - // Returns a reference to the DynamicField. - inline DynamicField<T, SizeMin>& shrink(); + //- Remove and return the top element + inline T remove(); - // Member Operators + // Member Operators - //- Append an element at the end of the list - inline DynamicField<T, SizeMin>& - append(const T& val); + //- Return non-const access to an element, resizing list if necessary + inline T& operator()(const label i); - //- Append a List at the end of this list - inline DynamicField<T, SizeMin>& - append(const UList<T>& lst); + //- Assign addressed entries to the given value + inline void operator=(const T& val); - //- Remove and return the top element - inline T remove(); + //- Copy assignment + inline void operator=(const UList<T>& list); - //- Return non-const access to an element, resizing list if - // necessary - inline T& operator()(const label i); + //- Copy assignment + inline void operator=(const DynamicField<T, SizeMin>& list); - //- Assignment of all addressed entries to the given value - inline void operator=(const T& val); + //- Move assignment + inline void operator=(List<T>&& list); - //- Assignment to DynamicField - inline void operator= - ( - const DynamicField<T, SizeMin>& lst - ); + //- Move assignment + inline void operator=(DynamicField<T, SizeMin>&& list); - //- Assignment to UList - inline void operator=(const UList<T>& lst); + //- Move assignment + template<int AnySizeMin> + inline void operator=(DynamicField<T, AnySizeMin>&& list); }; diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H b/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H index 1f7b5c479f516c429433e0d077f3bc464e7ccfcd..6fdb18241aa64988627e737a7a6931dd75b19171 100644 --- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H +++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H @@ -29,23 +29,23 @@ template<class T, int SizeMin> template<class ListType> inline void Foam::DynamicField<T, SizeMin>::assignDynField ( - const ListType& lst + const ListType& list ) { - const label newSize = lst.size(); + const label newSize = list.size(); if (capacity_ >= newSize) { // Can copy w/o reallocating - adjust addressable size accordingly. - Field<T>::size(lst.size()); - Field<T>::operator=(lst); + Field<T>::size(list.size()); + Field<T>::operator=(list); } else { // Ensure list size consistency prior to copying. Field<T>::size(capacity_); - Field<T>::operator=(lst); + Field<T>::operator=(list); capacity_ = Field<T>::size(); } } @@ -62,15 +62,11 @@ inline constexpr Foam::DynamicField<T, SizeMin>::DynamicField() noexcept template<class T, int SizeMin> -inline Foam::DynamicField<T, SizeMin>::DynamicField -( - const label len -) +inline Foam::DynamicField<T, SizeMin>::DynamicField(const label len) : Field<T>(len), capacity_(Field<T>::size()) { - // We could also enforce sizing granularity Field<T>::size(0); } @@ -78,21 +74,57 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField template<class T, int SizeMin> inline Foam::DynamicField<T, SizeMin>::DynamicField ( - const DynamicField<T, SizeMin>& lst + const label len, + const T& val +) +: + Field<T>(len, val), + capacity_(Field<T>::size()) +{} + + +template<class T, int SizeMin> +inline Foam::DynamicField<T, SizeMin>::DynamicField +( + const label len, + const zero +) +: + Field<T>(len, Zero), + capacity_(Field<T>::size()) +{} + + +template<class T, int SizeMin> +inline Foam::DynamicField<T, SizeMin>::DynamicField +( + const DynamicField<T, SizeMin>& list +) +: + Field<T>(list), + capacity_(Field<T>::size()) +{} + + +template<class T, int SizeMin> +template<int AnySizeMin> +inline Foam::DynamicField<T, SizeMin>::DynamicField +( + const DynamicField<T, AnySizeMin>& list ) : - Field<T>(lst), - capacity_(lst.capacity()) + Field<T>(list), + capacity_(Field<T>::size()) {} template<class T, int SizeMin> inline Foam::DynamicField<T, SizeMin>::DynamicField ( - const UList<T>& lst + const UList<T>& list ) : - Field<T>(lst), + Field<T>(list), capacity_(Field<T>::size()) {} @@ -100,10 +132,10 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField template<class T, int SizeMin> inline Foam::DynamicField<T, SizeMin>::DynamicField ( - const UIndirectList<T>& lst + const UIndirectList<T>& list ) : - Field<T>(lst), + Field<T>(list), capacity_(Field<T>::size()) {} @@ -125,10 +157,24 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField DynamicField<T, SizeMin>&& content ) : - Field<T>(std::move(content)), - capacity_(Field<T>::size()) + Field<T>(), + capacity_(0) +{ + transfer(content); +} + + +template<class T, int SizeMin> +template<int AnySizeMin> +inline Foam::DynamicField<T, SizeMin>::DynamicField +( + DynamicField<T, AnySizeMin>&& content +) +: + Field<T>(), + capacity_(0) { - content.clear(); + transfer(content); } @@ -173,8 +219,7 @@ inline Foam::DynamicField<T, SizeMin>::DynamicField // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template<class T, int SizeMin> -inline Foam::label Foam::DynamicField<T, SizeMin>::capacity() -const +inline Foam::label Foam::DynamicField<T, SizeMin>::capacity() const { return capacity_; } @@ -343,6 +388,73 @@ Foam::DynamicField<T, SizeMin>::shrink() } +template<class T, int SizeMin> +template<int AnySizeMin> +inline void Foam::DynamicField<T, SizeMin>::swap +( + DynamicField<T, AnySizeMin>& lst +) +{ + DynamicList<T, SizeMin>& cur = *this; + + // Make addressable size identical to the allocated capacity + const label oldSize1 = cur.expandStorage(); + const label oldSize2 = lst.expandStorage(); + + // Swap storage + Field<T>::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<class T, int SizeMin> +inline void Foam::DynamicField<T, SizeMin>::transfer(List<T>& list) +{ + // Take over storage, clear addressing for list. + capacity_ = list.size(); + Field<T>::transfer(list); +} + + +template<class T, int SizeMin> +template<int AnySizeMin> +inline void Foam::DynamicField<T, SizeMin>::transfer +( + DynamicList<T, AnySizeMin>& list +) +{ + // Take over storage as-is (without shrink, without using SizeMin) + // clear addressing and storage for old list. + capacity_ = list.capacity(); + + Field<T>::transfer(static_cast<Field<T>&>(list)); + list.clearStorage(); // Ensure capacity=0 +} + + +template<class T, int SizeMin> +template<int AnySizeMin> +inline void Foam::DynamicField<T, SizeMin>::transfer +( + DynamicField<T, AnySizeMin>& list +) +{ + // Take over storage as-is (without shrink, without using SizeMin) + // clear addressing and storage for old list. + capacity_ = list.capacity(); + + Field<T>::transfer(static_cast<Field<T>&>(list)); + list.clearStorage(); // Ensure capacity=0 +} + + template<class T, int SizeMin> inline Foam::DynamicField<T, SizeMin>& Foam::DynamicField<T, SizeMin>::append @@ -353,7 +465,7 @@ Foam::DynamicField<T, SizeMin>::append const label idx = List<T>::size(); setSize(idx + 1); - this->operator[](idx) = val; + this->operator[](idx) = val; // copy element return *this; } @@ -362,21 +474,21 @@ template<class T, int SizeMin> inline Foam::DynamicField<T, SizeMin>& Foam::DynamicField<T, SizeMin>::append ( - const UList<T>& lst + const UList<T>& list ) { - if (this == &lst) + if (this == &list) { FatalErrorInFunction << "attempted appending to self" << abort(FatalError); } - label nextFree = List<T>::size(); - setSize(nextFree + lst.size()); + label idx = List<T>::size(); + setSize(idx + list.size()); - forAll(lst, i) + for (const T& val : list) { - this->operator[](nextFree++) = lst[i]; + this->operator[](idx++) = val; // copy element } return *this; } @@ -432,26 +544,57 @@ inline void Foam::DynamicField<T, SizeMin>::operator= template<class T, int SizeMin> inline void Foam::DynamicField<T, SizeMin>::operator= ( - const DynamicField<T, SizeMin>& lst + const UList<T>& list ) { - if (this == &lst) + assignDynField(list); +} + + +template<class T, int SizeMin> +inline void Foam::DynamicField<T, SizeMin>::operator= +( + const DynamicField<T, SizeMin>& list +) +{ + if (this == &list) { FatalErrorInFunction << "Attempted assignment to self" << abort(FatalError); } - assignDynField(lst); + assignDynField(list); +} + + +template<class T, int SizeMin> +inline void Foam::DynamicField<T, SizeMin>::operator= +( + List<T>&& list +) +{ + transfer(list); +} + + +template<class T, int SizeMin> +inline void Foam::DynamicField<T, SizeMin>::operator= +( + DynamicField<T, SizeMin>&& list +) +{ + transfer(list); } template<class T, int SizeMin> +template<int AnySizeMin> inline void Foam::DynamicField<T, SizeMin>::operator= ( - const UList<T>& lst + DynamicField<T, AnySizeMin>&& list ) { - assignDynField(lst); + transfer(list); } diff --git a/src/OpenFOAM/fields/Fields/Field/FieldI.H b/src/OpenFOAM/fields/Fields/Field/FieldI.H index 10101a2b2f0e3ac030739bc286b46c368e2fb62e..987d647c6a821d2d839eef9e82db687f2afa6b77 100644 --- a/src/OpenFOAM/fields/Fields/Field/FieldI.H +++ b/src/OpenFOAM/fields/Fields/Field/FieldI.H @@ -186,5 +186,4 @@ inline void Foam::Field<Type>::operator=(const zero) } - // ************************************************************************* //