From e5c3e7de75e612283a1274be36bca540d34817f8 Mon Sep 17 00:00:00 2001 From: Mark Olesen 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 | 75 ++++++++++------ .../DimensionedField/DimensionedFieldIO.C | 5 +- .../FieldFields/FieldField/FieldField.C | 79 +++++++++++----- .../FieldFields/FieldField/FieldField.H | 40 ++++++--- .../GeometricField/GeometricBoundaryField.C | 49 +++------- .../GeometricField/GeometricField.C | 46 ++++++++++ .../GeometricField/GeometricField.H | 30 +++++-- 8 files changed, 273 insertions(+), 141 deletions(-) diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C index 09e89bc28a..94d80dea5c 100644 --- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C +++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C @@ -120,6 +120,26 @@ Foam::DimensionedField::DimensionedField } +template +Foam::DimensionedField::DimensionedField +( + const IOobject& io, + const Mesh& mesh, + const dimensionSet& dims, + const tmp>& tfield +) +: + regIOobject(io), + Field(tfield.constCast(), tfield.movable()), + mesh_(mesh), + dimensions_(dims), + oriented_() +{ + tfield.clear(); + checkFieldSize(); +} + + template Foam::DimensionedField::DimensionedField ( @@ -181,26 +201,22 @@ Foam::DimensionedField::DimensionedField template Foam::DimensionedField::DimensionedField ( - DimensionedField& df, - bool reuse + DimensionedField&& df ) : - regIOobject(df, reuse), - Field(df, reuse), - mesh_(df.mesh_), - dimensions_(df.dimensions_), - oriented_(df.oriented_) + DimensionedField(df, true) {} template Foam::DimensionedField::DimensionedField ( - DimensionedField&& df + DimensionedField& df, + bool reuse ) : - regIOobject(df, true), - Field(std::move(df)), + regIOobject(df, reuse), + Field(df, reuse), mesh_(df.mesh_), dimensions_(df.dimensions_), oriented_(df.oriented_) @@ -214,11 +230,7 @@ Foam::DimensionedField::DimensionedField const tmp>& tdf ) : - regIOobject(tdf.constCast(), tdf.movable()), - Field(tdf.constCast(), tdf.movable()), - mesh_(tdf().mesh_), - dimensions_(tdf().dimensions_), - oriented_(tdf().oriented_) + DimensionedField(tdf.constCast(), tdf.movable()) { tdf.clear(); } @@ -240,6 +252,17 @@ Foam::DimensionedField::DimensionedField {} +template +Foam::DimensionedField::DimensionedField +( + const IOobject& io, + DimensionedField&& df +) +: + DimensionedField(io, df, true) +{} + + template Foam::DimensionedField::DimensionedField ( @@ -256,6 +279,21 @@ Foam::DimensionedField::DimensionedField {} +#ifndef NoConstructFromTmp +template +Foam::DimensionedField::DimensionedField +( + const IOobject& io, + const tmp>& tdf +) +: + DimensionedField(io, tdf.constCast(), tdf.movable()) +{ + tdf.clear(); +} +#endif + + template Foam::DimensionedField::DimensionedField ( @@ -275,15 +313,10 @@ template Foam::DimensionedField::DimensionedField ( const word& newName, - DimensionedField& df, - bool reuse + DimensionedField&& df ) : - regIOobject(newName, df, true), - Field(df, reuse), - mesh_(df.mesh_), - dimensions_(df.dimensions_), - oriented_(df.oriented_) + DimensionedField(newName, df, true) {} @@ -291,11 +324,12 @@ template Foam::DimensionedField::DimensionedField ( const word& newName, - DimensionedField&& df + DimensionedField& df, + bool reuse ) : regIOobject(newName, df, true), - Field(std::move(df)), + Field(df, reuse), mesh_(df.mesh_), dimensions_(df.dimensions_), oriented_(df.oriented_) @@ -310,11 +344,7 @@ Foam::DimensionedField::DimensionedField const tmp>& tdf ) : - regIOobject(newName, tdf(), true), - Field(tdf.constCast(), tdf.movable()), - mesh_(tdf().mesh_), - dimensions_(tdf().dimensions_), - oriented_(tdf().oriented_) + DimensionedField(newName, tdf.constCast(), tdf.movable()) { tdf.clear(); } @@ -356,7 +386,7 @@ Foam::DimensionedField::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 23d721f203..6bebd04c8b 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 DimensionedField; -template Ostream& operator<< +template +Ostream& operator<< ( Ostream& os, const DimensionedField& df ); -template Ostream& operator<< +template +Ostream& operator<< ( Ostream& os, const tmp>& tdf @@ -152,6 +153,15 @@ public: List&& field ); + //- Construct from components, copy or transfer tmp content + DimensionedField + ( + const IOobject& io, + const Mesh& mesh, + const dimensionSet& dims, + const tmp>& 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& df - ); - - //- Copy construct or reuse (move) as specified. - DimensionedField - ( - DimensionedField& df, - bool reuse - ); + DimensionedField(const DimensionedField& df); //- Move construct - explicit DimensionedField - ( - DimensionedField&& df - ); + DimensionedField(DimensionedField&& df); - //- Construct as copy of tmp deleting argument + //- Copy construct or reuse (move) as specified. + DimensionedField(DimensionedField& df, bool reuse); + + //- Construct from tmp\ deleting argument #ifndef NoConstructFromTmp DimensionedField ( @@ -225,6 +225,13 @@ public: const DimensionedField& df ); + //- Move construct, resetting IO parameters + DimensionedField + ( + const IOobject& io, + DimensionedField&& df + ); + //- Copy or move construct, resetting IO parameters. DimensionedField ( @@ -233,13 +240,30 @@ public: bool reuse ); - //- Copy construct, resetting name + //- Construct from tmp\ deleting argument, + //- resetting IO parameters. + #ifndef NoConstructFromTmp + DimensionedField + ( + const IOobject& io, + const tmp>& tdf + ); + #endif + + //- Copy construct with a new name DimensionedField ( const word& newName, const DimensionedField& df ); + //- Move construct with a new name + DimensionedField + ( + const word& newName, + DimensionedField&& df + ); + //- Copy or move construct, resetting name. DimensionedField ( @@ -248,14 +272,7 @@ public: bool reuse ); - //- Move construct with a new name - DimensionedField - ( - const word& newName, - DimensionedField&& df - ); - - //- Construct as copy resetting name + //- Construct with a new name from tmp\ #ifndef NoConstructFromTmp DimensionedField ( diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C index 612785cdfc..cb1895f525 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 @@ -81,7 +80,7 @@ Foam::DimensionedField::DimensionedField ) : regIOobject(io), - Field(0), + Field(), mesh_(mesh), dimensions_(dimless), oriented_() @@ -100,7 +99,7 @@ Foam::DimensionedField::DimensionedField ) : regIOobject(io), - Field(0), + Field(), mesh_(mesh), dimensions_(dimless), oriented_() diff --git a/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.C b/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.C index ad98f6a02f..f729227600 100644 --- a/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.C +++ b/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.C @@ -132,24 +132,37 @@ FieldField::FieldField template class Field, class Type> -FieldField::FieldField(const FieldField& f) +FieldField::FieldField(const FieldField& ff) : - refCount(), - PtrList>(f) + PtrList>(ff) {} template class Field, class Type> -FieldField::FieldField(FieldField& f, bool reuse) +FieldField::FieldField(FieldField&& ff) : - PtrList>(f, reuse) + PtrList>(std::move(ff)) {} template class Field, class Type> -FieldField::FieldField(const PtrList>& tl) +FieldField::FieldField(FieldField& ff, bool reuse) : - PtrList>(tl) + PtrList>(ff, reuse) +{} + + +template class Field, class Type> +FieldField::FieldField(const PtrList>& list) +: + PtrList>(list) +{} + + +template class Field, class Type> +FieldField::FieldField(PtrList>&& list) +: + PtrList>(std::move(list)) {} @@ -185,17 +198,17 @@ tmp> FieldField::NewCalculatedType const FieldField& ff ) { - FieldField* nffPtr - ( - new FieldField(ff.size()) - ); + const label len = ff.size(); - forAll(*nffPtr, i) + auto tresult = tmp>::New(len); + auto& result = tresult.ref(); + + for (label i=0; iset(i, Field::NewCalculatedType(ff[i]).ptr()); + result.set(i, Field::NewCalculatedType(ff[i]).ptr()); } - return tmp>(nffPtr); + return tresult; } @@ -261,13 +274,13 @@ void FieldField::replace template class Field, class Type> tmp> FieldField::T() const { - tmp> transpose + auto tresult ( FieldField::NewCalculatedType(*this) ); - ::Foam::T(transpose.ref(), *this); - return transpose; + ::Foam::T(tresult.ref(), *this); + return tresult; } @@ -282,6 +295,7 @@ void FieldField::operator=(const FieldField& f) << "attempted assignment to self" << abort(FatalError); } + // No size checking done forAll(*this, i) { @@ -291,19 +305,38 @@ void FieldField::operator=(const FieldField& f) template class Field, class Type> -void FieldField::operator=(const tmp& tf) +void FieldField::operator=(FieldField&& ff) { - if (this == &(tf())) + if (this == &ff) { FatalErrorInFunction << "attempted assignment to self" << abort(FatalError); } - // This is dodgy stuff, don't try this at home. - FieldField* fieldPtr = tf.ptr(); - PtrList>::transfer(*fieldPtr); - delete fieldPtr; + PtrList>::transfer(ff); +} + + +template class Field, class Type> +void FieldField::operator=(const tmp& tf) +{ + // The cref() method also checks that tmp is not nullptr. + if (this == &(tf.cref())) + { + FatalErrorInFunction + << "attempted assignment to self" + << abort(FatalError); + } + + PtrList>::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>::transfer(*tptr); + delete tptr; } diff --git a/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.H b/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.H index bae0375b68..690e1df64b 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&); + //- Clone construct with new type + FieldField(const word& type, const FieldField& ff); - //- Construct as copy - FieldField(const FieldField&); + //- Copy construct, cloning each element + FieldField(const FieldField& ff); + + //- Move construct + FieldField(FieldField&& ff); //- Construct as copy or re-use as specified. - FieldField(FieldField&, bool reuse); + FieldField(FieldField& ff, bool reuse); - //- Construct as copy of a PtrList - FieldField(const PtrList>&); + //- Copy construct from PtrList + FieldField(const PtrList>& list); - //- Construct as copy of tmp + //- Move construct from PtrList + FieldField(PtrList>&& list); + + //- Move/copy construct from tmp #ifndef NoConstructFromTmp - FieldField(const tmp>&); + FieldField(const tmp>& tf); #endif //- Construct from Istream - FieldField(Istream&); + FieldField(Istream& is); //- Clone tmp> clone() const; @@ -147,8 +151,16 @@ public: // Member operators + //- Copy assignment void operator=(const FieldField&); + + //- Move assignment + void operator=(FieldField&&); + + //- Move or clone assignment void operator=(const tmp>&); + + //- Assign uniform value void operator=(const Type&); void operator+=(const FieldField&); diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C index ee127be278..2ebf52925c 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(bmesh.size()), bmesh_(bmesh) { - if (debug) - { - InfoInFunction << endl; - } + DebugInFunction << nl; forAll(bmesh_, patchi) { @@ -251,10 +244,7 @@ Boundary FieldField(bmesh.size()), bmesh_(bmesh) { - if (debug) - { - InfoInFunction << endl; - } + DebugInFunction << nl; if ( @@ -318,10 +308,7 @@ Boundary FieldField(bmesh.size()), bmesh_(bmesh) { - if (debug) - { - InfoInFunction << endl; - } + DebugInFunction << nl; forAll(bmesh_, patchi) { @@ -342,10 +329,7 @@ Boundary FieldField(btf.size()), bmesh_(btf.bmesh_) { - if (debug) - { - InfoInFunction << endl; - } + DebugInFunction << nl; forAll(bmesh_, patchi) { @@ -365,10 +349,7 @@ Boundary FieldField(btf), bmesh_(btf.bmesh_) { - if (debug) - { - InfoInFunction << endl; - } + DebugInFunction << nl; } @@ -394,10 +375,7 @@ template class PatchField, class GeoMesh> void Foam::GeometricField::Boundary:: updateCoeffs() { - if (debug) - { - InfoInFunction << endl; - } + DebugInFunction << nl; forAll(*this, patchi) { @@ -410,10 +388,7 @@ template class PatchField, class GeoMesh> void Foam::GeometricField::Boundary:: evaluate() { - if (debug) - { - InfoInFunction << endl; - } + DebugInFunction << nl; if ( @@ -479,14 +454,14 @@ types() const { const FieldField& 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 e7a088c522..df75d2ac64 100644 --- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C +++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C @@ -304,6 +304,52 @@ Foam::GeometricField::GeometricField } +template class PatchField, class GeoMesh> +Foam::GeometricField::GeometricField +( + const IOobject& io, + const Mesh& mesh, + const dimensionSet& ds, + const Field& 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 PatchField, class GeoMesh> +Foam::GeometricField::GeometricField +( + const IOobject& io, + const Mesh& mesh, + const dimensionSet& ds, + Field&& 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 PatchField, class GeoMesh> Foam::GeometricField::GeometricField ( diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H index a7941db125..d9ac7efa0e 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>& ptfl ); + //- Copy construct from internal field, with specified patch type + GeometricField + ( + const IOobject& io, + const Mesh& mesh, + const dimensionSet& ds, + const Field& iField, + const word& patchFieldType = PatchField::calculatedType() + ); + + //- Move construct from internal field, with specified patch type + GeometricField + ( + const IOobject& io, + const Mesh& mesh, + const dimensionSet& ds, + Field&& iField, + const word& patchFieldType = PatchField::calculatedType() + ); + //- Copy construct from components GeometricField ( @@ -376,7 +396,7 @@ public: const GeometricField& gf ); - //- Construct as copy of tmp deleting argument + //- Construct from tmp\ 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& gf ); - //- Construct as copy resetting name + //- Construct with a new name from tmp\ #ifndef NoConstructFromTmp GeometricField (