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
This commit is contained in:
Mark Olesen
2018-10-12 18:58:28 +02:00
parent 8eddcc072a
commit e5c3e7de75
8 changed files with 273 additions and 141 deletions

View File

@ -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;
}

View File

@ -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);
//- Construct as copy of tmp<DimensionedField> deleting argument
//- Copy construct or reuse (move) as specified.
DimensionedField(DimensionedField<Type, GeoMesh>& df, bool reuse);
//- 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,13 +240,30 @@ public:
bool reuse
);
//- Copy construct, resetting name
//- Construct from tmp\<DimensionedField\> deleting argument,
//- resetting IO parameters.
#ifndef NoConstructFromTmp
DimensionedField
(
const IOobject& io,
const tmp<DimensionedField<Type, GeoMesh>>& tdf
);
#endif
//- Copy construct with a new name
DimensionedField
(
const word& newName,
const DimensionedField<Type, GeoMesh>& df
);
//- Move construct with a new name
DimensionedField
(
const word& newName,
DimensionedField<Type, GeoMesh>&& 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<Type, GeoMesh>&& df
);
//- Construct as copy resetting name
//- Construct with a new name from tmp\<DimensionedField\>
#ifndef NoConstructFromTmp
DimensionedField
(

View File

@ -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_()

View File

@ -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();
forAll(*nffPtr, i)
auto tresult = tmp<FieldField<Field, Type>>::New(len);
auto& result = tresult.ref();
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)
{
@ -291,19 +305,38 @@ void FieldField<Field, Type>::operator=(const FieldField<Field, Type>& f)
template<template<class> class Field, class Type>
void FieldField<Field, Type>::operator=(const tmp<FieldField>& tf)
void FieldField<Field, Type>::operator=(FieldField<Field, Type>&& 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<Field<Type>>::transfer(*fieldPtr);
delete fieldPtr;
PtrList<Field<Type>>::transfer(ff);
}
template<template<class> class Field, class Type>
void FieldField<Field, Type>::operator=(const tmp<FieldField>& tf)
{
// The cref() method also checks that tmp is not nullptr.
if (this == &(tf.cref()))
{
FatalErrorInFunction
<< "attempted assignment to self"
<< abort(FatalError);
}
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;
}

View File

@ -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);
//- Construct as copy
FieldField(const FieldField<Field, Type>&);
//- Copy construct, cloning each element
FieldField(const FieldField<Field, Type>& ff);
//- 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);
//- Construct as copy of a PtrList<Field, Type>
FieldField(const PtrList<Field<Type>>&);
//- Copy construct from PtrList
FieldField(const PtrList<Field<Type>>& list);
//- Construct as copy of tmp<FieldField>
//- Move construct from PtrList
FieldField(PtrList<Field<Type>>&& list);
//- 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>&);

View File

@ -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;
}

View File

@ -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
(

View File

@ -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
(