diff --git a/applications/test/tmp/Make/files b/applications/test/tmp/Make/files
new file mode 100644
index 0000000000..5b4ecf10aa
--- /dev/null
+++ b/applications/test/tmp/Make/files
@@ -0,0 +1,3 @@
+Test-tmp.C
+
+EXE = $(FOAM_USER_APPBIN)/Test-tmp
diff --git a/applications/test/tmpField/Make/options b/applications/test/tmp/Make/options
similarity index 100%
rename from applications/test/tmpField/Make/options
rename to applications/test/tmp/Make/options
diff --git a/applications/test/tmpField/Test-tmpField.C b/applications/test/tmp/Test-tmp.C
similarity index 59%
rename from applications/test/tmpField/Test-tmpField.C
rename to applications/test/tmp/Test-tmp.C
index 6896344ec5..73ba236063 100644
--- a/applications/test/tmpField/Test-tmpField.C
+++ b/applications/test/tmp/Test-tmp.C
@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
- \\/ M anipulation |
+ \\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@@ -22,10 +22,10 @@ License
along with OpenFOAM. If not, see .
Application
- tmpFieldTest
+ Test-tmp
Description
- Tests for possible memory leaks in the tmp algebra.
+ Tests for possible memory leaks in the tmp (and tmp algebra).
\*---------------------------------------------------------------------------*/
@@ -33,19 +33,50 @@ Description
using namespace Foam;
+struct myScalarField : public scalarField
+{
+ using scalarField::scalarField;
+};
+
+
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main()
{
- scalarField f1(1000000, 1.0), f2(1000000, 2.0), f3(1000000, 3.0);
-
- for (;;)
{
- f1 = f2 + f3 + f2 + f3;
+ scalarField f1(1000000, 1.0), f2(1000000, 2.0), f3(1000000, 3.0);
+
+ for (int iter=0; iter < 50; ++iter)
+ {
+ f1 = f2 + f3 + f2 + f3;
+ }
+
+ Info<<"f1 = " << f1 << nl;
}
- Info<< "end" << endl;
+ {
+ tmp tfld1 = tmp::New(20, Zero);
+
+ Info<< "tmp refCount = " << tfld1->count() << nl;
+ if (tfld1.valid())
+ {
+ Info<<"tmp: " << tfld1() << nl;
+ }
+ }
+
+ {
+ tmp tfld2 =
+ tmp::NewFrom(20, Zero);
+
+ Info<< "tmp refCount = " << tfld2->count() << nl;
+ if (tfld2.valid())
+ {
+ Info<<"tmp: " << tfld2() << nl;
+ }
+ }
+
+ Info<< "\nEnd" << endl;
}
diff --git a/applications/test/tmpField/Make/files b/applications/test/tmpField/Make/files
deleted file mode 100644
index c3dd60a71d..0000000000
--- a/applications/test/tmpField/Make/files
+++ /dev/null
@@ -1,3 +0,0 @@
-Test-tmpField.C
-
-EXE = $(FOAM_USER_APPBIN)/Test-tmpField
diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C
index e4717cd7fe..f2f54f3270 100644
--- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C
+++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.C
@@ -217,12 +217,8 @@ DimensionedField::DimensionedField
const tmp>& tdf
)
:
- regIOobject(tdf(), tdf.isTmp()),
- Field
- (
- const_cast&>(tdf()),
- tdf.isTmp()
- ),
+ regIOobject(tdf.constCast(), tdf.movable()),
+ Field(tdf.constCast(), tdf.movable()),
mesh_(tdf().mesh_),
dimensions_(tdf().dimensions_),
oriented_(tdf().oriented_)
@@ -318,11 +314,7 @@ DimensionedField::DimensionedField
)
:
regIOobject(newName, tdf(), true),
- Field
- (
- const_cast&>(tdf()),
- tdf.isTmp()
- ),
+ Field(tdf.constCast(), tdf.movable()),
mesh_(tdf().mesh_),
dimensions_(tdf().dimensions_),
oriented_(tdf().oriented_)
@@ -511,7 +503,7 @@ void DimensionedField::operator=
const tmp>& tdf
)
{
- const DimensionedField& df = tdf();
+ auto& df = tdf.constCast();
// Check for assignment to self
if (this == &df)
@@ -525,7 +517,7 @@ void DimensionedField::operator=
dimensions_ = df.dimensions();
oriented_ = df.oriented();
- this->transfer(const_cast&>(df));
+ this->transfer(df);
tdf.clear();
}
diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldReuseFunctions.H b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldReuseFunctions.H
index 3cf47f0cd5..967eace9ad 100644
--- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldReuseFunctions.H
+++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldReuseFunctions.H
@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
- \\/ M anipulation |
+ \\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@@ -41,32 +41,31 @@ tmp> New
const dimensionSet& dimensions
)
{
- DimensionedField& df1 =
- const_cast&>(tdf1());
-
if (tdf1.isTmp())
{
+ auto& df1 = tdf1.constCast();
+
df1.rename(name);
df1.dimensions().reset(dimensions);
return tdf1;
}
- else
- {
- return tmp>
+
+ const auto& df1 = tdf1();
+
+ return tmp>
+ (
+ new DimensionedField
(
- new DimensionedField
+ IOobject
(
- IOobject
- (
- name,
- df1.instance(),
- df1.db()
- ),
- df1.mesh(),
- dimensions
- )
- );
- }
+ name,
+ df1.instance(),
+ df1.db()
+ ),
+ df1.mesh(),
+ dimensions
+ )
+ );
}
@@ -82,7 +81,7 @@ public:
const dimensionSet& dimensions
)
{
- const DimensionedField& df1 = tdf1();
+ const auto& df1 = tdf1();
return tmp>
(
@@ -114,32 +113,31 @@ public:
const dimensionSet& dimensions
)
{
- DimensionedField& df1 =
- const_cast&>(tdf1());
-
if (tdf1.isTmp())
{
+ auto& df1 = tdf1.constCast();
+
df1.rename(name);
df1.dimensions().reset(dimensions);
return tdf1;
}
- else
- {
- return tmp>
+
+ const auto& df1 = tdf1();
+
+ return tmp>
+ (
+ new DimensionedField
(
- new DimensionedField
+ IOobject
(
- IOobject
- (
- name,
- df1.instance(),
- df1.db()
- ),
- df1.mesh(),
- dimensions
- )
- );
- }
+ name,
+ df1.instance(),
+ df1.db()
+ ),
+ df1.mesh(),
+ dimensions
+ )
+ );
}
};
@@ -157,7 +155,7 @@ public:
const dimensionSet& dimensions
)
{
- const DimensionedField& df1 = tdf1();
+ const auto& df1 = tdf1();
return tmp>
(
@@ -190,33 +188,31 @@ public:
const dimensionSet& dimensions
)
{
- const DimensionedField& df1 = tdf1();
- DimensionedField& df2 =
- const_cast&>(tdf2());
-
if (tdf2.isTmp())
{
+ auto& df2 = tdf2.constCast();
+
df2.rename(name);
df2.dimensions().reset(dimensions);
return tdf2;
}
- else
- {
- return tmp>
+
+ const auto& df1 = tdf1();
+
+ return tmp>
+ (
+ new DimensionedField
(
- new DimensionedField
+ IOobject
(
- IOobject
- (
- name,
- df1.instance(),
- df1.db()
- ),
- df1.mesh(),
- dimensions
- )
- );
- }
+ name,
+ df1.instance(),
+ df1.db()
+ ),
+ df1.mesh(),
+ dimensions
+ )
+ );
}
};
@@ -234,32 +230,31 @@ public:
const dimensionSet& dimensions
)
{
- DimensionedField& df1 =
- const_cast&>(tdf1());
-
if (tdf1.isTmp())
{
+ auto& df1 = tdf1.constCast();
+
df1.rename(name);
df1.dimensions().reset(dimensions);
return tdf1;
}
- else
- {
- return tmp>
+
+ const auto& df1 = tdf1();
+
+ return tmp>
+ (
+ new DimensionedField
(
- new DimensionedField
+ IOobject
(
- IOobject
- (
- name,
- df1.instance(),
- df1.db()
- ),
- df1.mesh(),
- dimensions
- )
- );
- }
+ name,
+ df1.instance(),
+ df1.db()
+ ),
+ df1.mesh(),
+ dimensions
+ )
+ );
}
};
@@ -277,40 +272,39 @@ public:
const dimensionSet& dimensions
)
{
- DimensionedField& df1 =
- const_cast&>(tdf1());
- DimensionedField& df2 =
- const_cast&>(tdf2());
-
if (tdf1.isTmp())
{
+ auto& df1 = tdf1.constCast();
+
df1.rename(name);
df1.dimensions().reset(dimensions);
return tdf1;
}
else if (tdf2.isTmp())
{
+ auto& df2 = tdf2.constCast();
+
df2.rename(name);
df2.dimensions().reset(dimensions);
return tdf2;
}
- else
- {
- return tmp>
+
+ const auto& df1 = tdf1();
+
+ return tmp>
+ (
+ new DimensionedField
(
- new DimensionedField
+ IOobject
(
- IOobject
- (
- name,
- df1.instance(),
- df1.db()
- ),
- df1.mesh(),
- dimensions
- )
- );
- }
+ name,
+ df1.instance(),
+ df1.db()
+ ),
+ df1.mesh(),
+ dimensions
+ )
+ );
}
};
diff --git a/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.C b/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.C
index 940afea59b..48610c8f97 100644
--- a/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.C
+++ b/src/OpenFOAM/fields/FieldFields/FieldField/FieldField.C
@@ -160,11 +160,7 @@ FieldField::FieldField(const PtrList>& tl)
template class Field, class Type>
FieldField::FieldField(const tmp>& tf)
:
- PtrList>
- (
- const_cast&>(tf()),
- tf.isTmp()
- )
+ PtrList>(tf.constCast(), tf.movable())
{
tf.clear();
}
diff --git a/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldReuseFunctions.H b/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldReuseFunctions.H
index 0006d9aa01..43383f1eb5 100644
--- a/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldReuseFunctions.H
+++ b/src/OpenFOAM/fields/FieldFields/FieldField/FieldFieldReuseFunctions.H
@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
- \\/ M anipulation |
+ \\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@@ -44,20 +44,18 @@ tmp> New
{
return tf1;
}
- else
+
+ tmp> rtf
+ (
+ FieldField::NewCalculatedType(tf1())
+ );
+
+ if (initRet)
{
- tmp> rtf
- (
- FieldField::NewCalculatedType(tf1())
- );
-
- if (initRet)
- {
- rtf.ref() = tf1();
- }
-
- return rtf;
+ rtf.ref() = tf1();
}
+
+ return rtf;
}
@@ -93,13 +91,11 @@ public:
{
return tf1;
}
- else
- {
- return tmp>
- (
- FieldField::NewCalculatedType(tf1())
- );
- }
+
+ return tmp>
+ (
+ FieldField::NewCalculatedType(tf1())
+ );
}
};
@@ -145,13 +141,11 @@ public:
{
return tf2;
}
- else
- {
- return tmp>
- (
- FieldField::NewCalculatedType(tf1())
- );
- }
+
+ return tmp>
+ (
+ FieldField::NewCalculatedType(tf1())
+ );
}
};
@@ -171,13 +165,11 @@ public:
{
return tf1;
}
- else
- {
- return tmp>
- (
- FieldField::NewCalculatedType(tf1())
- );
- }
+
+ return tmp>
+ (
+ FieldField::NewCalculatedType(tf1())
+ );
}
};
@@ -201,13 +193,11 @@ public:
{
return tf2;
}
- else
- {
- return tmp>
- (
- FieldField::NewCalculatedType(tf1())
- );
- }
+
+ return tmp>
+ (
+ FieldField::NewCalculatedType(tf1())
+ );
}
};
diff --git a/src/OpenFOAM/fields/Fields/Field/Field.C b/src/OpenFOAM/fields/Fields/Field/Field.C
index eaaf483064..321fdb1029 100644
--- a/src/OpenFOAM/fields/Fields/Field/Field.C
+++ b/src/OpenFOAM/fields/Fields/Field/Field.C
@@ -256,7 +256,7 @@ Foam::Field::Field(const UIndirectList& list)
template
Foam::Field::Field(const tmp>& tf)
:
- List(const_cast&>(tf()), tf.isTmp())
+ List(tf.constCast(), tf.movable())
{
tf.clear();
}
diff --git a/src/OpenFOAM/fields/Fields/Field/FieldReuseFunctions.H b/src/OpenFOAM/fields/Fields/Field/FieldReuseFunctions.H
index fac9e9a51c..3818628c3e 100644
--- a/src/OpenFOAM/fields/Fields/Field/FieldReuseFunctions.H
+++ b/src/OpenFOAM/fields/Fields/Field/FieldReuseFunctions.H
@@ -44,17 +44,15 @@ tmp> New
{
return tf1;
}
- else
+
+ tmp> rtf(new Field(tf1().size()));
+
+ if (initRet)
{
- tmp> rtf(new Field(tf1().size()));
-
- if (initRet)
- {
- rtf.ref() = tf1();
- }
-
- return rtf;
+ rtf.ref() = tf1();
}
+
+ return rtf;
}
@@ -81,10 +79,8 @@ public:
{
return tf1;
}
- else
- {
- return tmp>(new Field(tf1().size()));
- }
+
+ return tmp>(new Field(tf1().size()));
}
};
@@ -120,10 +116,8 @@ public:
{
return tf2;
}
- else
- {
- return tmp>(new Field(tf1().size()));
- }
+
+ return tmp>(new Field(tf1().size()));
}
};
@@ -143,10 +137,8 @@ public:
{
return tf1;
}
- else
- {
- return tmp>(new Field(tf1().size()));
- }
+
+ return tmp>(new Field(tf1().size()));
}
};
@@ -170,10 +162,8 @@ public:
{
return tf2;
}
- else
- {
- return tmp>(new Field(tf1().size()));
- }
+
+ return tmp>(new Field(tf1().size()));
}
};
diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C
index 6f2c45eb6f..6fd5a97ce5 100644
--- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C
+++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.C
@@ -455,11 +455,7 @@ Foam::GeometricField::GeometricField
const tmp>& tgf
)
:
- Internal
- (
- const_cast&>(tgf()),
- tgf.isTmp()
- ),
+ Internal(tgf.constCast(), tgf.movable()),
timeIndex_(tgf().timeIndex()),
field0Ptr_(nullptr),
fieldPrevIterPtr_(nullptr),
@@ -517,12 +513,7 @@ Foam::GeometricField::GeometricField
const tmp>& tgf
)
:
- Internal
- (
- io,
- const_cast&>(tgf()),
- tgf.isTmp()
- ),
+ Internal(io, tgf.constCast(), tgf.movable()),
timeIndex_(tgf().timeIndex()),
field0Ptr_(nullptr),
fieldPrevIterPtr_(nullptr),
@@ -581,12 +572,7 @@ Foam::GeometricField::GeometricField
const tmp>& tgf
)
:
- Internal
- (
- newName,
- const_cast&>(tgf()),
- tgf.isTmp()
- ),
+ Internal(newName, tgf.constCast(), tgf.movable()),
timeIndex_(tgf().timeIndex()),
field0Ptr_(nullptr),
fieldPrevIterPtr_(nullptr),
@@ -690,12 +676,7 @@ Foam::GeometricField::GeometricField
const wordList& actualPatchTypes
)
:
- Internal
- (
- io,
- const_cast&>(tgf()),
- tgf.isTmp()
- ),
+ Internal(io, tgf.constCast(), tgf.movable()),
timeIndex_(tgf().timeIndex()),
field0Ptr_(nullptr),
fieldPrevIterPtr_(nullptr),
@@ -1221,7 +1202,7 @@ void Foam::GeometricField::operator=
this->dimensions() = gf.dimensions();
this->oriented() = gf.oriented();
- if (tgf.isTmp())
+ if (tgf.movable())
{
// Transfer the storage from the tmp
primitiveFieldRef().transfer
diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H
index 3162084d4d..0b13a145b2 100644
--- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H
+++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricField.H
@@ -125,16 +125,16 @@ public:
// Constructors
//- Construct from a BoundaryMesh
- Boundary(const BoundaryMesh&);
+ Boundary(const BoundaryMesh& bmesh);
//- Construct from a BoundaryMesh,
// reference to the internal field
// and a patch type
Boundary
(
- const BoundaryMesh&,
- const Internal&,
- const word&
+ const BoundaryMesh& bmesh,
+ const Internal& field,
+ const word& patchFieldType
);
//- Construct from a BoundaryMesh,
@@ -143,8 +143,8 @@ public:
// types (to override constraint patches)
Boundary
(
- const BoundaryMesh&,
- const Internal&,
+ const BoundaryMesh& bmesh,
+ const Internal& field,
const wordList& wantedPatchTypes,
const wordList& actualPatchTypes = wordList()
);
@@ -154,16 +154,16 @@ public:
// and a PtrList>
Boundary
(
- const BoundaryMesh&,
- const Internal&,
+ const BoundaryMesh& bmesh,
+ const Internal& field,
const PtrList>&
);
//- Construct as copy setting the reference to the internal field
Boundary
(
- const Internal&,
- const Boundary&
+ const Internal& field,
+ const Boundary& btf
);
//- Construct as copy
@@ -173,14 +173,14 @@ public:
// BoundaryField for which such operations are unavailable.
Boundary
(
- const Boundary&
+ const Boundary& btf
);
//- Construct from dictionary
Boundary
(
- const BoundaryMesh&,
- const Internal&,
+ const BoundaryMesh& bmesh,
+ const Internal& field,
const dictionary&
);
diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldReuseFunctions.H b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldReuseFunctions.H
index c6fb56706d..df17b18468 100644
--- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldReuseFunctions.H
+++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricFieldReuseFunctions.H
@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
- \\/ M anipulation |
+ \\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@@ -45,9 +45,8 @@ bool reusable(const tmp>& tgf)
{
if (GeometricField::debug)
{
- const GeometricField& gf = tgf();
- const typename GeometricField::
- Boundary& gbf = gf.boundaryField();
+ const auto& gf = tgf();
+ const auto& gbf = gf.boundaryField();
forAll(gbf, patchi)
{
@@ -68,10 +67,8 @@ bool reusable(const tmp>& tgf)
return true;
}
- else
- {
- return false;
- }
+
+ return false;
}
@@ -84,39 +81,38 @@ tmp> New
const bool initRet = false
)
{
- GeometricField& gf1 =
- const_cast&>(tgf1());
-
if (reusable(tgf1))
{
+ auto& gf1 = tgf1.constCast();
+
gf1.rename(name);
gf1.dimensions().reset(dimensions);
return tgf1;
}
- else
- {
- tmp> rtgf
+
+ const auto& gf1 = tgf1();
+
+ tmp> rtgf
+ (
+ new GeometricField
(
- new GeometricField
+ IOobject
(
- IOobject
- (
- name,
- gf1.instance(),
- gf1.db()
- ),
- gf1.mesh(),
- dimensions
- )
- );
+ name,
+ gf1.instance(),
+ gf1.db()
+ ),
+ gf1.mesh(),
+ dimensions
+ )
+ );
- if (initRet)
- {
- rtgf.ref() == tgf1();
- }
-
- return rtgf;
+ if (initRet)
+ {
+ rtgf.ref() == gf1;
}
+
+ return rtgf;
}
@@ -138,7 +134,7 @@ public:
const dimensionSet& dimensions
)
{
- const GeometricField& gf1 = tgf1();
+ const auto& gf1 = tgf1();
return tmp>
(
@@ -170,32 +166,31 @@ public:
const dimensionSet& dimensions
)
{
- GeometricField& gf1 =
- const_cast&>(tgf1());
-
if (reusable(tgf1))
{
+ auto& gf1 = tgf1.constCast();
+
gf1.rename(name);
gf1.dimensions().reset(dimensions);
return tgf1;
}
- else
- {
- return tmp>
+
+ const auto& gf1 = tgf1();
+
+ return tmp>
+ (
+ new GeometricField
(
- new GeometricField
+ IOobject
(
- IOobject
- (
- name,
- gf1.instance(),
- gf1.db()
- ),
- gf1.mesh(),
- dimensions
- )
- );
- }
+ name,
+ gf1.instance(),
+ gf1.db()
+ ),
+ gf1.mesh(),
+ dimensions
+ )
+ );
}
};
@@ -221,7 +216,7 @@ public:
const dimensionSet& dimensions
)
{
- const GeometricField& gf1 = tgf1();
+ const auto& gf1 = tgf1();
return tmp>
(
@@ -262,33 +257,31 @@ public:
const dimensionSet& dimensions
)
{
- const GeometricField& gf1 = tgf1();
- GeometricField& gf2 =
- const_cast&>(tgf2());
-
if (reusable(tgf2))
{
+ auto& gf2 = tgf2.constCast();
+
gf2.rename(name);
gf2.dimensions().reset(dimensions);
return tgf2;
}
- else
- {
- return tmp>
+
+ const auto& gf1 = tgf1();
+
+ return tmp>
+ (
+ new GeometricField
(
- new GeometricField
+ IOobject
(
- IOobject
- (
- name,
- gf1.instance(),
- gf1.db()
- ),
- gf1.mesh(),
- dimensions
- )
- );
- }
+ name,
+ gf1.instance(),
+ gf1.db()
+ ),
+ gf1.mesh(),
+ dimensions
+ )
+ );
}
};
@@ -312,32 +305,31 @@ public:
const dimensionSet& dimensions
)
{
- GeometricField& gf1 =
- const_cast&>(tgf1());
-
if (reusable(tgf1))
{
+ auto& gf1 = tgf1.constCast();
+
gf1.rename(name);
gf1.dimensions().reset(dimensions);
return tgf1;
}
- else
- {
- return tmp>
+
+ const auto& gf1 = tgf1();
+
+ return tmp>
+ (
+ new GeometricField
(
- new GeometricField
+ IOobject
(
- IOobject
- (
- name,
- gf1.instance(),
- gf1.db()
- ),
- gf1.mesh(),
- dimensions
- )
- );
- }
+ name,
+ gf1.instance(),
+ gf1.db()
+ ),
+ gf1.mesh(),
+ dimensions
+ )
+ );
}
};
@@ -355,40 +347,39 @@ public:
const dimensionSet& dimensions
)
{
- GeometricField& gf1 =
- const_cast&>(tgf1());
- GeometricField& gf2 =
- const_cast&>(tgf2());
-
if (reusable(tgf1))
{
+ auto& gf1 = tgf1.constCast();
+
gf1.rename(name);
gf1.dimensions().reset(dimensions);
return tgf1;
}
else if (reusable(tgf2))
{
+ auto& gf2 = tgf2.constCast();
+
gf2.rename(name);
gf2.dimensions().reset(dimensions);
return tgf2;
}
- else
- {
- return tmp>
+
+ const auto& gf1 = tgf1();
+
+ return tmp>
+ (
+ new GeometricField
(
- new GeometricField
+ IOobject
(
- IOobject
- (
- name,
- gf1.instance(),
- gf1.db()
- ),
- gf1.mesh(),
- dimensions
- )
- );
- }
+ name,
+ gf1.instance(),
+ gf1.db()
+ ),
+ gf1.mesh(),
+ dimensions
+ )
+ );
}
};
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixTemplates.C b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixTemplates.C
index 0ac399fb59..9f28ad17cd 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixTemplates.C
+++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixTemplates.C
@@ -98,15 +98,13 @@ Foam::lduMatrix::faceH(const Field& psi) const
return tfaceHpsi;
}
- else
- {
- FatalErrorInFunction
- << "Cannot calculate faceH"
- " the matrix does not have any off-diagonal coefficients."
- << exit(FatalError);
- return tmp>(nullptr);
- }
+ FatalErrorInFunction
+ << "Cannot calculate faceH"
+ " the matrix does not have any off-diagonal coefficients."
+ << exit(FatalError);
+
+ return tmp>();
}
diff --git a/src/OpenFOAM/memory/refCount/refCount.H b/src/OpenFOAM/memory/refCount/refCount.H
index 1f90ba73a4..5b6e22c681 100644
--- a/src/OpenFOAM/memory/refCount/refCount.H
+++ b/src/OpenFOAM/memory/refCount/refCount.H
@@ -53,6 +53,10 @@ class refCount
public:
+ //- A non-counting (dummy) refCount
+ struct zero {};
+
+
// Constructors
//- Construct null initializing count to 0
diff --git a/src/OpenFOAM/memory/tmp/tmp.H b/src/OpenFOAM/memory/tmp/tmp.H
index 52dc896a83..736a7c4cca 100644
--- a/src/OpenFOAM/memory/tmp/tmp.H
+++ b/src/OpenFOAM/memory/tmp/tmp.H
@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
- \\/ M anipulation |
+ \\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@@ -25,14 +25,19 @@ Class
Foam::tmp
Description
- A class for managing temporary objects
+ A class for managing temporary objects.
+
+ This is a combination of std::shared_ptr (with intrusive ref-counting)
+ and a shared_ptr without ref-counting and null deleter.
+ This allows the tmp to double as a pointer management and an indirect
+ pointer to externally allocated objects.
SourceFiles
tmpI.H
See also
- Foam::refCount
Foam::autoPtr
+ Foam::refCount
\*---------------------------------------------------------------------------*/
@@ -41,6 +46,7 @@ See also
#include "refCount.H"
#include "word.H"
+#include
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -57,111 +63,201 @@ class tmp
// Private data
//- Object types
- enum type
+ enum refType
{
- TMP,
- CONST_REF
+ PTR, //!< Managing a (ref-counted) pointer
+ CREF //!< Using a const-reference to an object
};
- //- Pointer to object
+ //- The managed pointer or the address of const-reference object
mutable T* ptr_;
- //- Type of object
- type type_;
+ //- The type (managed pointer | const-reference object)
+ mutable refType type_;
- // Private member operators
+ // Private Member Operators
+ //- Increment the ref-count for a managed pointer
inline void operator++();
public:
- typedef T Type;
+ // STL type definitions
+
+ //- Type of object being managed or referenced
+ typedef T element_type;
+
+ //- Pointer to type of object being managed or referenced
+ typedef T* pointer;
+
+
+ //- Reference counter class
typedef Foam::refCount refCount;
+ // Factory Methods
+
+ //- Construct tmp of T with forwarding arguments
+ // \param args list of arguments with which an instance of T
+ // will be constructed.
+ //
+ // \note Similar to std::make_shared, but the overload for
+ // array types is not disabled.
+ template
+ inline static tmp New(Args&&... args);
+
+ //- Construct tmp from derived type with forwarding arguments
+ // \param args list of arguments with which an instance of U
+ // will be constructed.
+ //
+ // \note Similar to New but for derived types
+ template
+ inline static tmp NewFrom(Args&&... args);
+
+
// Constructors
- //- Null pointer construct
- inline tmp();
+ //- Construct with no managed pointer.
+ inline constexpr tmp() noexcept;
- //- Store object pointer
+ //- Construct with no managed pointer.
+ inline constexpr tmp(std::nullptr_t) noexcept;
+
+ //- Construct, taking ownership of the pointer.
inline explicit tmp(T* p);
- //- Store object const reference
- inline tmp(const T& t);
+ //- Construct for a const reference to an object.
+ inline tmp(const T& obj) noexcept;
- //- Construct copy and increment reference count
+ //- Move construct, transferring ownership.
+ // Does not affect ref-count
+ inline tmp(tmp&& t) noexcept;
+
+ //- Move construct, transferring ownership.
+ // Does not affect ref-count
+ // \note Non-standard definition - should be non-const
+ inline tmp(const tmp&& t) noexcept;
+
+ //- Copy construct, incrementing ref-count of managed pointer.
+ // \note Non-standard definition - should be non-const
inline tmp(const tmp& t);
- //- Construct copy moving content, does not increment reference count
- inline tmp(const tmp&& t);
-
- //- Construct copy transferring content of temporary if required
- inline tmp(const tmp& t, bool allowTransfer);
+ //- Copy construct. Optionally reusing ref-counted pointer.
+ inline tmp(const tmp& t, bool reuse);
- //- Destructor: deletes temporary object when the reference count is 0
+ //- Destructor: deletes managed pointer when the ref-count is 0
inline ~tmp();
// Member Functions
- // Access
+ // Query
- //- Return true if this is really a temporary object
- inline bool isTmp() const;
+ //- True if this is a managed pointer (not a const reference)
+ inline bool isTmp() const;
- //- Return true if this temporary object empty,
- // ie, a temporary without allocation
- inline bool empty() const;
+ //- True if this is a non-null managed pointer
+ inline bool empty() const;
- //- Is this temporary object valid,
- // ie, it is a reference or a temporary that has been allocated
- inline bool valid() const;
+ //- True if this is a non-null managed pointer,
+ //- or is a const object reference
+ inline bool valid() const;
- //- Return the type name of the tmp
- // constructed from the type name of T
- inline word typeName() const;
+ //- True if this is a non-null managed pointer with a unique ref-count
+ inline bool movable() const;
+
+ //- Return type-name of the tmp, constructed from type-name of T
+ inline word typeName() const;
- // Edit
+ // Access
- //- Return tmp pointer for reuse.
- // Returns a clone if the object is not a temporary
- inline T* ptr() const;
+ //- Return the const object reference or a const reference to the
+ //- contents of a non-null managed pointer.
+ // Fatal for a null managed pointer
+ inline const T& cref() const;
- //- Return non-const reference. Fatal if the object is const.
- inline T& ref() const;
+ //- Return non-const reference to the contents of a non-null
+ //- managed pointer.
+ // Fatal for a null managed pointer or if the object is const.
+ inline T& ref() const;
- //- If object pointer points to valid object:
- //- delete object and set pointer to nullptr
- inline void clear() const;
+ //- Non-const dereference, even if the object is const.
+ // This is similar to ref(), but applies a const_cast to access
+ // const objects.
+ // Fatal for a null managed pointer.
+ inline T& constCast() const;
+
+
+ // Edit
+
+ //- Return managed pointer for reuse, or clone() the const object
+ //- reference.
+ inline T* ptr() const;
+
+ //- If object pointer points to valid object:
+ //- delete object and set pointer to nullptr
+ inline void clear() const;
+
+ //- Release ownership of managed temporary object.
+ // After this call no object is managed.
+ inline void reset();
+
+ //- Delete managed temporary object and set to new given pointer
+ inline void reset(T* p);
+
+ //- Swaps the managed object with other tmp.
+ inline void swap(tmp& other) noexcept;
// Member operators
- //- Const dereference operator
+ //- Return const reference to the object.
+ // Identical to cref() method.
inline const T& operator()() const;
- //- Const cast to the underlying type reference
+ //- Cast to underlying data type, using the cref() method.
inline operator const T&() const;
- //- Return object pointer
- inline T* operator->();
-
- //- Return const object pointer
+ //- Dereferences (const) pointer to the managed object.
+ // Fatal for a null managed pointer.
inline const T* operator->() const;
- //- Assignment to pointer changing this tmp to a temporary T
+ //- Dereferences (non-const) pointer to the managed object.
+ // Fatal for a null managed pointer or if the object is const.
+ inline T* operator->();
+
+ //- Take ownership of the pointer.
+ // Fatal for a null pointer, or when the pointer is non-unique.
inline void operator=(T* p);
- //- Assignment transferring the temporary T to this tmp
+ //- Transfer ownership of the managed pointer.
+ // Fatal for a null managed pointer or if the object is const.
inline void operator=(const tmp& t);
+
+
+ // Housekeeping
+
+ //- Disallow assignment from literal nullptr.
+ // Consistent with run-time check for nullptr on assignment.
+ void operator=(std::nullptr_t) = delete;
};
+// Global Functions
+
+//- Specializes the Swap algorithm for tmp.
+// Swaps the pointers and types of lhs and rhs. Calls \c lhs.swap(rhs)
+template
+void Swap(tmp& lhs, tmp& rhs)
+{
+ lhs.swap(rhs);
+}
+
+
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
diff --git a/src/OpenFOAM/memory/tmp/tmpI.H b/src/OpenFOAM/memory/tmp/tmpI.H
index c789bc0dbf..c2729bc1c7 100644
--- a/src/OpenFOAM/memory/tmp/tmpI.H
+++ b/src/OpenFOAM/memory/tmp/tmpI.H
@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
- \\/ M anipulation |
+ \\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@@ -43,13 +43,39 @@ inline void Foam::tmp::operator++()
}
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+template
+template
+inline Foam::tmp Foam::tmp::New(Args&&... args)
+{
+ return tmp(new T(std::forward(args)...));
+}
+
+
+template
+template
+inline Foam::tmp Foam::tmp::NewFrom(Args&&... args)
+{
+ return tmp(new U(std::forward(args)...));
+}
+
+
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template
-inline Foam::tmp::tmp()
+inline constexpr Foam::tmp::tmp() noexcept
:
ptr_(nullptr),
- type_(TMP)
+ type_(PTR)
+{}
+
+
+template
+inline constexpr Foam::tmp::tmp(std::nullptr_t) noexcept
+:
+ ptr_(nullptr),
+ type_(PTR)
{}
@@ -57,7 +83,7 @@ template
inline Foam::tmp::tmp(T* p)
:
ptr_(p),
- type_(TMP)
+ type_(PTR)
{
if (p && !p->unique())
{
@@ -70,13 +96,35 @@ inline Foam::tmp::tmp(T* p)
template
-inline Foam::tmp::tmp(const T& t)
+inline Foam::tmp::tmp(const T& obj) noexcept
:
- ptr_(const_cast(&t)),
- type_(CONST_REF)
+ ptr_(const_cast(&obj)),
+ type_(CREF)
{}
+template
+inline Foam::tmp::tmp(tmp&& t) noexcept
+:
+ ptr_(t.ptr_),
+ type_(t.type_)
+{
+ t.ptr_ = nullptr;
+ t.type_ = PTR;
+}
+
+
+template
+inline Foam::tmp::tmp(const tmp&& t) noexcept
+:
+ ptr_(t.ptr_),
+ type_(t.type_)
+{
+ t.ptr_ = nullptr;
+ t.type_ = PTR;
+}
+
+
template
inline Foam::tmp::tmp(const tmp& t)
:
@@ -100,20 +148,7 @@ inline Foam::tmp::tmp(const tmp& t)
template
-inline Foam::tmp::tmp(const tmp&& t)
-:
- ptr_(t.ptr_),
- type_(t.type_)
-{
- if (isTmp())
- {
- t.ptr_ = nullptr;
- }
-}
-
-
-template
-inline Foam::tmp::tmp(const tmp& t, bool allowTransfer)
+inline Foam::tmp::tmp(const tmp& t, bool reuse)
:
ptr_(t.ptr_),
type_(t.type_)
@@ -122,9 +157,9 @@ inline Foam::tmp::tmp(const tmp& t, bool allowTransfer)
{
if (ptr_)
{
- if (allowTransfer)
+ if (reuse)
{
- t.ptr_ = nullptr;
+ t.ptr_ = nullptr; // t.type_ already set as PTR
}
else
{
@@ -153,21 +188,28 @@ inline Foam::tmp::~tmp()
template
inline bool Foam::tmp::isTmp() const
{
- return type_ == TMP;
+ return type_ == PTR;
}
template
inline bool Foam::tmp::empty() const
{
- return (isTmp() && !ptr_);
+ return (!ptr_ && isTmp());
}
template
inline bool Foam::tmp::valid() const
{
- return (!isTmp() || (isTmp() && ptr_));
+ return (ptr_ || type_ == CREF);
+}
+
+
+template
+inline bool Foam::tmp::movable() const
+{
+ return (type_ == PTR && ptr_ && ptr_->unique());
}
@@ -179,7 +221,7 @@ inline Foam::word Foam::tmp::typeName() const
template
-inline T* Foam::tmp::ptr() const
+inline const T& Foam::tmp::cref() const
{
if (isTmp())
{
@@ -189,22 +231,9 @@ inline T* Foam::tmp::ptr() const
<< typeName() << " deallocated"
<< abort(FatalError);
}
-
- if (!ptr_->unique())
- {
- FatalErrorInFunction
- << "Attempt to acquire pointer to object referred to"
- << " by multiple temporaries of type " << typeName()
- << abort(FatalError);
- }
-
- T* ptr = ptr_;
- ptr_ = nullptr;
-
- return ptr;
}
- return ptr_->clone().ptr();
+ return *ptr_; // const reference
}
@@ -223,12 +252,55 @@ inline T& Foam::tmp