From e5c3e7de75e612283a1274be36bca540d34817f8 Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Fri, 12 Oct 2018 18:58:28 +0200 Subject: [PATCH] ENH: COMP: handle compiler ambiguities for tmp vs movable references - seen with gcc-4.9.4, but not with gcc-7 - provide additional constructors from tmp for DimensionedField, FieldField --- .../DimensionedField/DimensionedField.C | 90 ++++++++++++------- .../DimensionedField/DimensionedField.H | 71 +++++++++------ .../DimensionedField/DimensionedFieldIO.C | 5 +- .../FieldFields/FieldField/FieldField.C | 77 +++++++++++----- .../FieldFields/FieldField/FieldField.H | 40 ++++++--- .../GeometricField/GeometricBoundaryField.C | 49 +++------- .../GeometricField/GeometricField.C | 46 ++++++++++ .../GeometricField/GeometricField.H | 30 +++++-- 8 files changed, 270 insertions(+), 138 deletions(-) diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C index 09e89bc28a9..94d80dea5c1 100644 --- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C +++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C @@ -120,6 +120,26 @@ Foam::DimensionedField<Type, GeoMesh>::DimensionedField } +template<class Type, class GeoMesh> +Foam::DimensionedField<Type, GeoMesh>::DimensionedField +( + const IOobject& io, + const Mesh& mesh, + const dimensionSet& dims, + const tmp<Field<Type>>& tfield +) +: + regIOobject(io), + Field<Type>(tfield.constCast(), tfield.movable()), + mesh_(mesh), + dimensions_(dims), + oriented_() +{ + tfield.clear(); + checkFieldSize(); +} + + template<class Type, class GeoMesh> Foam::DimensionedField<Type, GeoMesh>::DimensionedField ( @@ -181,26 +201,22 @@ Foam::DimensionedField<Type, GeoMesh>::DimensionedField template<class Type, class GeoMesh> Foam::DimensionedField<Type, GeoMesh>::DimensionedField ( - DimensionedField<Type, GeoMesh>& df, - bool reuse + DimensionedField<Type, GeoMesh>&& df ) : - regIOobject(df, reuse), - Field<Type>(df, reuse), - mesh_(df.mesh_), - dimensions_(df.dimensions_), - oriented_(df.oriented_) + DimensionedField<Type, GeoMesh>(df, true) {} template<class Type, class GeoMesh> Foam::DimensionedField<Type, GeoMesh>::DimensionedField ( - DimensionedField<Type, GeoMesh>&& df + DimensionedField<Type, GeoMesh>& df, + bool reuse ) : - regIOobject(df, true), - Field<Type>(std::move(df)), + regIOobject(df, reuse), + Field<Type>(df, reuse), mesh_(df.mesh_), dimensions_(df.dimensions_), oriented_(df.oriented_) @@ -214,11 +230,7 @@ Foam::DimensionedField<Type, GeoMesh>::DimensionedField const tmp<DimensionedField<Type, GeoMesh>>& tdf ) : - regIOobject(tdf.constCast(), tdf.movable()), - Field<Type>(tdf.constCast(), tdf.movable()), - mesh_(tdf().mesh_), - dimensions_(tdf().dimensions_), - oriented_(tdf().oriented_) + DimensionedField<Type, GeoMesh>(tdf.constCast(), tdf.movable()) { tdf.clear(); } @@ -240,6 +252,17 @@ Foam::DimensionedField<Type, GeoMesh>::DimensionedField {} +template<class Type, class GeoMesh> +Foam::DimensionedField<Type, GeoMesh>::DimensionedField +( + const IOobject& io, + DimensionedField<Type, GeoMesh>&& df +) +: + DimensionedField<Type, GeoMesh>(io, df, true) +{} + + template<class Type, class GeoMesh> Foam::DimensionedField<Type, GeoMesh>::DimensionedField ( @@ -256,6 +279,21 @@ Foam::DimensionedField<Type, GeoMesh>::DimensionedField {} +#ifndef NoConstructFromTmp +template<class Type, class GeoMesh> +Foam::DimensionedField<Type, GeoMesh>::DimensionedField +( + const IOobject& io, + const tmp<DimensionedField<Type, GeoMesh>>& tdf +) +: + DimensionedField<Type, GeoMesh>(io, tdf.constCast(), tdf.movable()) +{ + tdf.clear(); +} +#endif + + template<class Type, class GeoMesh> Foam::DimensionedField<Type, GeoMesh>::DimensionedField ( @@ -275,15 +313,10 @@ template<class Type, class GeoMesh> Foam::DimensionedField<Type, GeoMesh>::DimensionedField ( const word& newName, - DimensionedField<Type, GeoMesh>& df, - bool reuse + DimensionedField<Type, GeoMesh>&& df ) : - regIOobject(newName, df, true), - Field<Type>(df, reuse), - mesh_(df.mesh_), - dimensions_(df.dimensions_), - oriented_(df.oriented_) + DimensionedField<Type, GeoMesh>(newName, df, true) {} @@ -291,11 +324,12 @@ template<class Type, class GeoMesh> Foam::DimensionedField<Type, GeoMesh>::DimensionedField ( const word& newName, - DimensionedField<Type, GeoMesh>&& df + DimensionedField<Type, GeoMesh>& df, + bool reuse ) : regIOobject(newName, df, true), - Field<Type>(std::move(df)), + Field<Type>(df, reuse), mesh_(df.mesh_), dimensions_(df.dimensions_), oriented_(df.oriented_) @@ -310,11 +344,7 @@ Foam::DimensionedField<Type, GeoMesh>::DimensionedField const tmp<DimensionedField<Type, GeoMesh>>& tdf ) : - regIOobject(newName, tdf(), true), - Field<Type>(tdf.constCast(), tdf.movable()), - mesh_(tdf().mesh_), - dimensions_(tdf().dimensions_), - oriented_(tdf().oriented_) + DimensionedField<Type, GeoMesh>(newName, tdf.constCast(), tdf.movable()) { tdf.clear(); } @@ -356,7 +386,7 @@ Foam::DimensionedField<Type, GeoMesh>::component dimensions_ ); - Foam::component(tresult(), *this, d); + Foam::component(tresult.ref(), *this, d); return tresult; } diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.H b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.H index 23d721f2030..6bebd04c8b1 100644 --- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.H +++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.H @@ -48,17 +48,18 @@ SourceFiles namespace Foam { -// Forward declaration of friend functions and operators - +// Forward declarations template<class Type, class GeoMesh> class DimensionedField; -template<class Type, class GeoMesh> Ostream& operator<< +template<class Type, class GeoMesh> +Ostream& operator<< ( Ostream& os, const DimensionedField<Type, GeoMesh>& df ); -template<class Type, class GeoMesh> Ostream& operator<< +template<class Type, class GeoMesh> +Ostream& operator<< ( Ostream& os, const tmp<DimensionedField<Type, GeoMesh>>& tdf @@ -152,6 +153,15 @@ public: List<Type>&& field ); + //- Construct from components, copy or transfer tmp content + DimensionedField + ( + const IOobject& io, + const Mesh& mesh, + const dimensionSet& dims, + const tmp<Field<Type>>& tfield + ); + //- Construct from components, setting the initial size and assigning //- the dimensions, but not initialising any field values. // Used for temporary fields which are initialised after construction @@ -192,25 +202,15 @@ public: ); //- Copy construct - DimensionedField - ( - const DimensionedField<Type, GeoMesh>& df - ); - - //- Copy construct or reuse (move) as specified. - DimensionedField - ( - DimensionedField<Type, GeoMesh>& df, - bool reuse - ); + DimensionedField(const DimensionedField<Type, GeoMesh>& df); //- Move construct - explicit DimensionedField - ( - DimensionedField<Type, GeoMesh>&& df - ); + DimensionedField(DimensionedField<Type, GeoMesh>&& df); + + //- Copy construct or reuse (move) as specified. + DimensionedField(DimensionedField<Type, GeoMesh>& df, bool reuse); - //- Construct as copy of tmp<DimensionedField> deleting argument + //- Construct from tmp\<DimensionedField\> deleting argument #ifndef NoConstructFromTmp DimensionedField ( @@ -225,6 +225,13 @@ public: const DimensionedField<Type, GeoMesh>& df ); + //- Move construct, resetting IO parameters + DimensionedField + ( + const IOobject& io, + DimensionedField<Type, GeoMesh>&& df + ); + //- Copy or move construct, resetting IO parameters. DimensionedField ( @@ -233,19 +240,21 @@ public: bool reuse ); - //- Copy construct, resetting name + //- Construct from tmp\<DimensionedField\> deleting argument, + //- resetting IO parameters. + #ifndef NoConstructFromTmp DimensionedField ( - const word& newName, - const DimensionedField<Type, GeoMesh>& df + const IOobject& io, + const tmp<DimensionedField<Type, GeoMesh>>& tdf ); + #endif - //- Copy or move construct, resetting name. + //- Copy construct with a new name DimensionedField ( const word& newName, - DimensionedField<Type, GeoMesh>& df, - bool reuse + const DimensionedField<Type, GeoMesh>& df ); //- Move construct with a new name @@ -255,7 +264,15 @@ public: DimensionedField<Type, GeoMesh>&& df ); - //- Construct as copy resetting name + //- Copy or move construct, resetting name. + DimensionedField + ( + const word& newName, + DimensionedField<Type, GeoMesh>& df, + bool reuse + ); + + //- Construct with a new name from tmp\<DimensionedField\> #ifndef NoConstructFromTmp DimensionedField ( diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C index 612785cdfc2..cb1895f5258 100644 --- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C +++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C @@ -26,7 +26,6 @@ License #include "DimensionedField.H" #include "IOstreams.H" - // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template<class Type, class GeoMesh> @@ -81,7 +80,7 @@ Foam::DimensionedField<Type, GeoMesh>::DimensionedField ) : regIOobject(io), - Field<Type>(0), + Field<Type>(), mesh_(mesh), dimensions_(dimless), oriented_() @@ -100,7 +99,7 @@ Foam::DimensionedField<Type, GeoMesh>::DimensionedField ) : regIOobject(io), - Field<Type>(0), + Field<Type>(), mesh_(mesh), dimensions_(dimless), oriented_() diff --git a/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.C b/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.C index ad98f6a02f1..f7292276004 100644 --- a/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.C +++ b/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.C @@ -132,24 +132,37 @@ FieldField<Field, Type>::FieldField template<template<class> class Field, class Type> -FieldField<Field, Type>::FieldField(const FieldField<Field, Type>& f) +FieldField<Field, Type>::FieldField(const FieldField<Field, Type>& ff) : - refCount(), - PtrList<Field<Type>>(f) + PtrList<Field<Type>>(ff) {} template<template<class> class Field, class Type> -FieldField<Field, Type>::FieldField(FieldField<Field, Type>& f, bool reuse) +FieldField<Field, Type>::FieldField(FieldField<Field, Type>&& ff) : - PtrList<Field<Type>>(f, reuse) + PtrList<Field<Type>>(std::move(ff)) {} template<template<class> class Field, class Type> -FieldField<Field, Type>::FieldField(const PtrList<Field<Type>>& tl) +FieldField<Field, Type>::FieldField(FieldField<Field, Type>& ff, bool reuse) : - PtrList<Field<Type>>(tl) + PtrList<Field<Type>>(ff, reuse) +{} + + +template<template<class> class Field, class Type> +FieldField<Field, Type>::FieldField(const PtrList<Field<Type>>& list) +: + PtrList<Field<Type>>(list) +{} + + +template<template<class> class Field, class Type> +FieldField<Field, Type>::FieldField(PtrList<Field<Type>>&& list) +: + PtrList<Field<Type>>(std::move(list)) {} @@ -185,17 +198,17 @@ tmp<FieldField<Field, Type>> FieldField<Field, Type>::NewCalculatedType const FieldField<Field, Type2>& ff ) { - FieldField<Field, Type>* nffPtr - ( - new FieldField<Field, Type>(ff.size()) - ); + const label len = ff.size(); + + auto tresult = tmp<FieldField<Field, Type>>::New(len); + auto& result = tresult.ref(); - forAll(*nffPtr, i) + for (label i=0; i<len; ++i) { - nffPtr->set(i, Field<Type>::NewCalculatedType(ff[i]).ptr()); + result.set(i, Field<Type>::NewCalculatedType(ff[i]).ptr()); } - return tmp<FieldField<Field, Type>>(nffPtr); + return tresult; } @@ -261,13 +274,13 @@ void FieldField<Field, Type>::replace template<template<class> class Field, class Type> tmp<FieldField<Field, Type>> FieldField<Field, Type>::T() const { - tmp<FieldField<Field, Type>> transpose + auto tresult ( FieldField<Field, Type>::NewCalculatedType(*this) ); - ::Foam::T(transpose.ref(), *this); - return transpose; + ::Foam::T(tresult.ref(), *this); + return tresult; } @@ -282,6 +295,7 @@ void FieldField<Field, Type>::operator=(const FieldField<Field, Type>& f) << "attempted assignment to self" << abort(FatalError); } + // No size checking done forAll(*this, i) { @@ -290,20 +304,39 @@ void FieldField<Field, Type>::operator=(const FieldField<Field, Type>& f) } +template<template<class> class Field, class Type> +void FieldField<Field, Type>::operator=(FieldField<Field, Type>&& ff) +{ + if (this == &ff) + { + FatalErrorInFunction + << "attempted assignment to self" + << abort(FatalError); + } + + PtrList<Field<Type>>::transfer(ff); +} + + template<template<class> class Field, class Type> void FieldField<Field, Type>::operator=(const tmp<FieldField>& tf) { - if (this == &(tf())) + // The cref() method also checks that tmp is not nullptr. + if (this == &(tf.cref())) { FatalErrorInFunction << "attempted assignment to self" << abort(FatalError); } - // This is dodgy stuff, don't try this at home. - FieldField* fieldPtr = tf.ptr(); - PtrList<Field<Type>>::transfer(*fieldPtr); - delete fieldPtr; + PtrList<Field<Type>>::clear(); + + // Release the tmp pointer, or clone const reference for a new pointer. + // Error potential when tmp is non-unique. + + auto* tptr = tf.ptr(); + PtrList<Field<Type>>::transfer(*tptr); + delete tptr; } diff --git a/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.H b/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.H index bae0375b681..690e1df64be 100644 --- a/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.H +++ b/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.H @@ -25,7 +25,7 @@ Class Foam::FieldField Description - Generic field type. + A field of fields is a PtrList of fields with reference counting. SourceFiles FieldField.C @@ -91,29 +91,33 @@ public: //- Construct given size // Used for temporary fields which are initialised after construction - explicit FieldField(const label); + explicit FieldField(const label size); - //- Construct using the Field sizes from the given FieldField - // and the given Field type. - // Used for temporary fields which are initialised after construction - FieldField(const word&, const FieldField<Field, Type>&); + //- Clone construct with new type + FieldField(const word& type, const FieldField<Field, Type>& ff); + + //- Copy construct, cloning each element + FieldField(const FieldField<Field, Type>& ff); - //- Construct as copy - FieldField(const FieldField<Field, Type>&); + //- Move construct + FieldField(FieldField<Field, Type>&& ff); //- Construct as copy or re-use as specified. - FieldField(FieldField<Field, Type>&, bool reuse); + FieldField(FieldField<Field, Type>& ff, bool reuse); + + //- Copy construct from PtrList + FieldField(const PtrList<Field<Type>>& list); - //- Construct as copy of a PtrList<Field, Type> - FieldField(const PtrList<Field<Type>>&); + //- Move construct from PtrList + FieldField(PtrList<Field<Type>>&& list); - //- Construct as copy of tmp<FieldField> + //- Move/copy construct from tmp<FieldField> #ifndef NoConstructFromTmp - FieldField(const tmp<FieldField<Field, Type>>&); + FieldField(const tmp<FieldField<Field, Type>>& tf); #endif //- Construct from Istream - FieldField(Istream&); + FieldField(Istream& is); //- Clone tmp<FieldField<Field, Type>> clone() const; @@ -147,8 +151,16 @@ public: // Member operators + //- Copy assignment void operator=(const FieldField<Field, Type>&); + + //- Move assignment + void operator=(FieldField<Field, Type>&&); + + //- Move or clone assignment void operator=(const tmp<FieldField<Field, Type>>&); + + //- Assign uniform value void operator=(const Type&); void operator+=(const FieldField<Field, Type>&); diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C index ee127be2788..2ebf52925c7 100644 --- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C +++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C @@ -36,17 +36,13 @@ readField const dictionary& dict ) { + DebugInFunction << nl; + // Clear the boundary field if already initialised this->clear(); this->setSize(bmesh_.size()); - if (debug) - { - InfoInFunction << endl; - } - - label nUnset = this->size(); // 1. Handle explicit patch names. Note that there can be only one explicit @@ -217,10 +213,7 @@ Boundary FieldField<PatchField, Type>(bmesh.size()), bmesh_(bmesh) { - if (debug) - { - InfoInFunction << endl; - } + DebugInFunction << nl; forAll(bmesh_, patchi) { @@ -251,10 +244,7 @@ Boundary FieldField<PatchField, Type>(bmesh.size()), bmesh_(bmesh) { - if (debug) - { - InfoInFunction << endl; - } + DebugInFunction << nl; if ( @@ -318,10 +308,7 @@ Boundary FieldField<PatchField, Type>(bmesh.size()), bmesh_(bmesh) { - if (debug) - { - InfoInFunction << endl; - } + DebugInFunction << nl; forAll(bmesh_, patchi) { @@ -342,10 +329,7 @@ Boundary FieldField<PatchField, Type>(btf.size()), bmesh_(btf.bmesh_) { - if (debug) - { - InfoInFunction << endl; - } + DebugInFunction << nl; forAll(bmesh_, patchi) { @@ -365,10 +349,7 @@ Boundary FieldField<PatchField, Type>(btf), bmesh_(btf.bmesh_) { - if (debug) - { - InfoInFunction << endl; - } + DebugInFunction << nl; } @@ -394,10 +375,7 @@ template<class Type, template<class> class PatchField, class GeoMesh> void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: updateCoeffs() { - if (debug) - { - InfoInFunction << endl; - } + DebugInFunction << nl; forAll(*this, patchi) { @@ -410,10 +388,7 @@ template<class Type, template<class> class PatchField, class GeoMesh> void Foam::GeometricField<Type, PatchField, GeoMesh>::Boundary:: evaluate() { - if (debug) - { - InfoInFunction << endl; - } + DebugInFunction << nl; if ( @@ -479,14 +454,14 @@ types() const { const FieldField<PatchField, Type>& pff = *this; - wordList Types(pff.size()); + wordList list(pff.size()); forAll(pff, patchi) { - Types[patchi] = pff[patchi].type(); + list[patchi] = pff[patchi].type(); } - return Types; + return list; } diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C index e7a088c522e..df75d2ac64f 100644 --- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C +++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C @@ -304,6 +304,52 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField } +template<class Type, template<class> class PatchField, class GeoMesh> +Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField +( + const IOobject& io, + const Mesh& mesh, + const dimensionSet& ds, + const Field<Type>& iField, + const word& patchFieldType +) +: + Internal(io, mesh, ds, iField), + timeIndex_(this->time().timeIndex()), + field0Ptr_(nullptr), + fieldPrevIterPtr_(nullptr), + boundaryField_(mesh.boundary(), *this, patchFieldType) +{ + DebugInFunction + << "Copy construct from internal field" << nl << this->info() << endl; + + readIfPresent(); +} + + +template<class Type, template<class> class PatchField, class GeoMesh> +Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField +( + const IOobject& io, + const Mesh& mesh, + const dimensionSet& ds, + Field<Type>&& iField, + const word& patchFieldType +) +: + Internal(io, mesh, ds, std::move(iField)), + timeIndex_(this->time().timeIndex()), + field0Ptr_(nullptr), + fieldPrevIterPtr_(nullptr), + boundaryField_(mesh.boundary(), *this, patchFieldType) +{ + DebugInFunction + << "Move construct from internal field" << nl << this->info() << endl; + + readIfPresent(); +} + + template<class Type, template<class> class PatchField, class GeoMesh> Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField ( diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H index a7941db125c..d9ac7efa0ed 100644 --- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H +++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H @@ -180,11 +180,11 @@ public: ( const BoundaryMesh& bmesh, const Internal& field, - const dictionary& + const dictionary& dict ); - // Member functions + // Member Functions //- Read the boundary field void readField @@ -344,6 +344,26 @@ public: const PtrList<PatchField<Type>>& ptfl ); + //- Copy construct from internal field, with specified patch type + GeometricField + ( + const IOobject& io, + const Mesh& mesh, + const dimensionSet& ds, + const Field<Type>& iField, + const word& patchFieldType = PatchField<Type>::calculatedType() + ); + + //- Move construct from internal field, with specified patch type + GeometricField + ( + const IOobject& io, + const Mesh& mesh, + const dimensionSet& ds, + Field<Type>&& iField, + const word& patchFieldType = PatchField<Type>::calculatedType() + ); + //- Copy construct from components GeometricField ( @@ -376,7 +396,7 @@ public: const GeometricField<Type, PatchField, GeoMesh>& gf ); - //- Construct as copy of tmp<GeometricField> deleting argument + //- Construct from tmp\<GeometricField\> deleting argument #ifndef NoConstructFromTmp GeometricField ( @@ -400,14 +420,14 @@ public: ); #endif - //- Construct as copy resetting name + //- Copy construct with a new name GeometricField ( const word& newName, const GeometricField<Type, PatchField, GeoMesh>& gf ); - //- Construct as copy resetting name + //- Construct with a new name from tmp\<GeometricField\> #ifndef NoConstructFromTmp GeometricField ( -- GitLab