From a8c40cc8c46af8f4fc19b0788fb2b2a7cb5db09b Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Thu, 8 Feb 2018 08:53:14 +0100
Subject: [PATCH] ENH: cleanup List constructors (issue #725)

- add copy construct from UList

- remove copy construct from dissimilar types.

  This templated constructor was too generous in what it accepted.
  For the special cases where a copy constructor is required with
  a change in the data type, now use the createList factory method,
  which accepts a unary operator. Eg,

      auto scalars = scalarList::createList
      (
          labels,
          [](const label& val){ return 1.5*val; }
      );
---
 applications/test/List/Test-List.C            | 107 ++++++++++
 .../manipulation/checkMesh/checkGeometry.C    |  12 +-
 .../moveDynamicMesh/moveDynamicMesh.C         |   6 +-
 .../foamFormatConvert/foamFormatConvert.C     |  30 ++-
 src/OpenFOAM/containers/Lists/List/List.C     | 192 ++++++++++++++----
 src/OpenFOAM/containers/Lists/List/List.H     |  76 ++++---
 src/OpenFOAM/containers/Lists/List/ListI.H    |  39 ++--
 .../containers/Lists/ListOps/ListOps.C        |   1 -
 src/OpenFOAM/db/Time/TimeIO.C                 |   4 +-
 src/OpenFOAM/primitives/ints/label/label.H    |  36 +++-
 10 files changed, 386 insertions(+), 117 deletions(-)

diff --git a/applications/test/List/Test-List.C b/applications/test/List/Test-List.C
index ec4ec9e5a1..945b0e9998 100644
--- a/applications/test/List/Test-List.C
+++ b/applications/test/List/Test-List.C
@@ -48,6 +48,23 @@ See also
 
 #include <list>
 #include <numeric>
+#include <functional>
+
+namespace Foam
+{
+
+// Verify inheritance
+class MyStrings
+:
+    public List<string>
+{
+public:
+
+    using List<string>::List;
+};
+
+} // end namespace Foam
+
 
 using namespace Foam;
 
@@ -66,6 +83,14 @@ void testFind(const T& val, const ListType& lst)
 }
 
 
+void printMyString(const UList<string>& lst)
+{
+    MyStrings slist2(lst);
+
+    Info<<slist2 << nl;
+}
+
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 //  Main program:
 
@@ -76,6 +101,7 @@ int main(int argc, char *argv[])
     argList::addOption("wordList", "wordList");
     argList::addOption("stringList", "stringList");
     argList::addOption("float", "xx");
+    argList::addBoolOption("transform", "Test List::createList functionality");
     argList::addBoolOption("flag");
 
     #include "setRootCase.H"
@@ -336,6 +362,85 @@ int main(int argc, char *argv[])
         Info<<"-flag:" << args["flag"] << endl;
     }
 
+    if (args.found("transform"))
+    {
+        Info<< nl << "Test List::createList functionality" << nl;
+
+        const auto labels = identity(15);
+        Info<< "labels: " << flatOutput(labels) << endl;
+
+        {
+            auto scalars = List<scalar>::createList
+            (
+                labels,
+                [](const label& val){ return scalar(1.5*val); }
+            );
+            Info<< "scalars: " << flatOutput(scalars) << endl;
+        }
+
+        {
+            auto vectors = List<vector>::createList
+            (
+                labels,
+                [](const label& val){ return vector(1.2*val, -1.2*val, 0); }
+            );
+            Info<< "vectors: " << flatOutput(vectors) << endl;
+        }
+
+        {
+            auto longs = List<long>::createList
+            (
+                labels,
+                [](const label& val){ return val; }
+            );
+            Info<< "longs: " << flatOutput(longs) << endl;
+        }
+        {
+            auto negs = List<label>::createList
+            (
+                labels,
+                std::negate<label>()
+            );
+            Info<< "negs: " << flatOutput(negs) << endl;
+        }
+
+        {
+            auto scalars = List<scalar>::createList
+            (
+                labelRange::null.cbegin(),
+                labelRange::identity(15).cend(),
+                [](const label& val){ return scalar(-1.125*val); }
+            );
+            Info<< "scalars: " << flatOutput(scalars) << endl;
+        }
+
+        #if WM_LABEL_SIZE == 32
+        {
+            List<int64_t> input(10);
+            std::iota(input.begin(), input.end(), 0);
+
+            auto output = List<label>::createList
+            (
+                input,
+                toLabel<int64_t>()
+            );
+            Info<< "label (from int64): " << flatOutput(output) << endl;
+        }
+        #elif WM_LABEL_SIZE == 64
+        {
+            List<int32_t> input(10);
+            std::iota(input.begin(), input.end(), 0);
+
+            auto output = List<label>::createList
+            (
+                input,
+                toLabel<int32_t>()
+            );
+            Info<< "label (from int32): " << flatOutput(output) << endl;
+        }
+        #endif
+    }
+
     if (args.readIfPresent<scalar>("float", xxx))
     {
         Info<<"read float " << xxx << endl;
@@ -354,6 +459,8 @@ int main(int argc, char *argv[])
     if (args.found("stringList"))
     {
         sLst = args.readList<string>("stringList");
+
+        printMyString(sLst);
     }
 
     Info<< nl
diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.C b/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.C
index a40a468269..12986a67c9 100644
--- a/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.C
+++ b/applications/utilities/mesh/manipulation/checkMesh/checkGeometry.C
@@ -1007,7 +1007,11 @@ Foam::label Foam::checkGeometry
                         globalFaces().gather
                         (
                             UPstream::worldComm,
-                            labelList(UPstream::procID(UPstream::worldComm)),
+                            labelList::createList
+                            (
+                                UPstream::procID(UPstream::worldComm),
+                                toLabel<int>()  // int -> label
+                            ),
                             ami.srcWeightsSum(),
                             mergedWeights
                         );
@@ -1057,7 +1061,11 @@ Foam::label Foam::checkGeometry
                         globalFaces().gather
                         (
                             UPstream::worldComm,
-                            labelList(UPstream::procID(UPstream::worldComm)),
+                            labelList::createList
+                            (
+                                UPstream::procID(UPstream::worldComm),
+                                toLabel<int>()  // int -> label
+                            ),
                             ami.tgtWeightsSum(),
                             mergedWeights
                         );
diff --git a/applications/utilities/mesh/manipulation/moveDynamicMesh/moveDynamicMesh.C b/applications/utilities/mesh/manipulation/moveDynamicMesh/moveDynamicMesh.C
index fa273ac807..f9961f0242 100644
--- a/applications/utilities/mesh/manipulation/moveDynamicMesh/moveDynamicMesh.C
+++ b/applications/utilities/mesh/manipulation/moveDynamicMesh/moveDynamicMesh.C
@@ -84,7 +84,11 @@ void writeWeights
     globalFaces().gather
     (
         UPstream::worldComm,
-        labelList(UPstream::procID(UPstream::worldComm)),
+        labelList::createList
+        (
+            UPstream::procID(UPstream::worldComm),
+            toLabel<int>()  // int -> label
+        ),
         wghtSum,
         mergedWeights
     );
diff --git a/applications/utilities/miscellaneous/foamFormatConvert/foamFormatConvert.C b/applications/utilities/miscellaneous/foamFormatConvert/foamFormatConvert.C
index 99447cf15d..3df5b240ae 100644
--- a/applications/utilities/miscellaneous/foamFormatConvert/foamFormatConvert.C
+++ b/applications/utilities/miscellaneous/foamFormatConvert/foamFormatConvert.C
@@ -162,13 +162,13 @@ bool writeZones(const word& name, const fileName& meshDir, Time& runTime)
 }
 
 
-// Reduction for non-empty strings
-class uniqueEqOp
+// Reduction for non-empty strings.
+template<class StringType>
+struct uniqueEqOp
 {
-    public:
-    void operator()(stringList& x, const stringList& y) const
+    void operator()(List<StringType>& x, const List<StringType>& y) const
     {
-        stringList newX(x.size()+y.size());
+        List<StringType> newX(x.size()+y.size());
         label n = 0;
         forAll(x, i)
         {
@@ -215,8 +215,8 @@ bool writeOptionalMeshObject
     bool haveFile = io.typeHeaderOk<IOField<label>>(false);
 
     // Make sure all know if there is a valid class name
-    stringList classNames(1, io.headerClassName());
-    combineReduce(classNames, uniqueEqOp());
+    wordList classNames(1, io.headerClassName());
+    combineReduce(classNames, uniqueEqOp<word>());
 
     // Check for correct type
     if (classNames[0] == T::typeName)
@@ -395,7 +395,7 @@ int main(int argc, char *argv[])
 
 
         // Check for lagrangian
-        stringList lagrangianDirs
+        fileNameList lagrangianDirs
         (
             1,
             fileHandler().filePath
@@ -406,7 +406,7 @@ int main(int argc, char *argv[])
             )
         );
 
-        combineReduce(lagrangianDirs, uniqueEqOp());
+        combineReduce(lagrangianDirs, uniqueEqOp<fileName>());
 
         if (!lagrangianDirs.empty())
         {
@@ -434,7 +434,7 @@ int main(int argc, char *argv[])
                 );
             }
 
-            stringList cloudDirs
+            fileNameList cloudDirs
             (
                 fileHandler().readDir
                 (
@@ -443,7 +443,7 @@ int main(int argc, char *argv[])
                 )
             );
 
-            combineReduce(cloudDirs, uniqueEqOp());
+            combineReduce(cloudDirs, uniqueEqOp<fileName>());
 
             forAll(cloudDirs, i)
             {
@@ -464,13 +464,11 @@ int main(int argc, char *argv[])
                 IOobjectList sprayObjs(runTime, runTime.timeName(), dir);
 
                 // Combine with all other cloud objects
-                stringList sprayFields(sprayObjs.sortedToc());
-                combineReduce(sprayFields, uniqueEqOp());
+                wordList sprayFields(sprayObjs.sortedToc());
+                combineReduce(sprayFields, uniqueEqOp<word>());
 
-                forAll(sprayFields, fieldi)
+                for (const word& name : sprayFields)
                 {
-                    const word& name = sprayFields[fieldi];
-
                     // Note: try the various field types. Make sure to
                     //       exit once sucessful conversion to avoid re-read
                     //       converted file.
diff --git a/src/OpenFOAM/containers/Lists/List/List.C b/src/OpenFOAM/containers/Lists/List/List.C
index 556de7b6f3..1e801804e9 100644
--- a/src/OpenFOAM/containers/Lists/List/List.C
+++ b/src/OpenFOAM/containers/Lists/List/List.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2017-2018 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -35,17 +35,76 @@ License
 
 #include <utility>
 
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+template<class T>
+template<class T2, class UnaryOperation>
+Foam::List<T> Foam::List<T>::createList
+(
+    const UList<T2>& input,
+    const UnaryOperation& op
+)
+{
+    const label len = input.size();
+
+    List<T> output(len);
+
+    if (len)
+    {
+        List_ACCESS(T, output, out);
+        List_CONST_ACCESS(T2, input, in);
+
+        for (label i = 0; i < len; ++i)
+        {
+            out[i] = op(in[i]);
+        }
+    }
+
+    return output;
+}
+
+
+template<class T>
+template<class InputIterator, class UnaryOperation>
+Foam::List<T> Foam::List<T>::createList
+(
+    InputIterator begIter,
+    InputIterator endIter,
+    const UnaryOperation& op
+)
+{
+    const label len = std::distance(begIter, endIter);
+
+    List<T> output(len);
+
+    if (len)
+    {
+        List_ACCESS(T, output, out);
+
+        InputIterator iter = begIter;
+
+        for (label i = 0; i < len; ++i)
+        {
+            out[i] = op(*iter);
+            ++iter;
+        }
+    }
+
+    return output;
+}
+
+
 // * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * * //
 
 template<class T>
-Foam::List<T>::List(const label s)
+Foam::List<T>::List(const label len)
 :
-    UList<T>(nullptr, s)
+    UList<T>(nullptr, len)
 {
-    if (this->size_ < 0)
+    if (len < 0)
     {
         FatalErrorInFunction
-            << "bad size " << this->size_
+            << "bad size " << len
             << abort(FatalError);
     }
 
@@ -54,23 +113,23 @@ Foam::List<T>::List(const label s)
 
 
 template<class T>
-Foam::List<T>::List(const label s, const T& val)
+Foam::List<T>::List(const label len, const T& val)
 :
-    UList<T>(nullptr, s)
+    UList<T>(nullptr, len)
 {
-    if (this->size_ < 0)
+    if (len < 0)
     {
         FatalErrorInFunction
-            << "bad size " << this->size_
+            << "bad size " << len
             << abort(FatalError);
     }
 
-    alloc();
-
-    if (this->size_)
+    if (len)
     {
+        alloc();
+
         List_ACCESS(T, (*this), vp);
-        List_FOR_ALL((*this), i)
+        for (label i=0; i < len; ++i)
         {
             vp[i] = val;
         }
@@ -79,23 +138,23 @@ Foam::List<T>::List(const label s, const T& val)
 
 
 template<class T>
-Foam::List<T>::List(const label s, const zero)
+Foam::List<T>::List(const label len, const zero)
 :
-    UList<T>(nullptr, s)
+    UList<T>(nullptr, len)
 {
-    if (this->size_ < 0)
+    if (len < 0)
     {
         FatalErrorInFunction
-            << "bad size " << this->size_
+            << "bad size " << len
             << abort(FatalError);
     }
 
-    alloc();
-
-    if (this->size_)
+    if (len)
     {
+        alloc();
+
         List_ACCESS(T, (*this), vp);
-        List_FOR_ALL((*this), i)
+        for (label i=0; i < len; ++i)
         {
             vp[i] = Zero;
         }
@@ -104,7 +163,7 @@ Foam::List<T>::List(const label s, const zero)
 
 
 template<class T>
-Foam::List<T>::List(const List<T>& a)
+Foam::List<T>::List(const UList<T>& a)
 :
     UList<T>(nullptr, a.size_)
 {
@@ -132,20 +191,28 @@ Foam::List<T>::List(const List<T>& a)
 
 
 template<class T>
-template<class T2>
-Foam::List<T>::List(const List<T2>& a)
+Foam::List<T>::List(const List<T>& a)
 :
-    UList<T>(nullptr, a.size())
+    UList<T>(nullptr, a.size_)
 {
     if (this->size_)
     {
         alloc();
 
-        List_ACCESS(T, (*this), vp);
-        List_CONST_ACCESS(T2, a, ap);
-        List_FOR_ALL((*this), i)
+        #ifdef USEMEMCPY
+        if (contiguous<T>())
         {
-            vp[i] = T(ap[i]);
+            memcpy(this->v_, a.v_, this->byteSize());
+        }
+        else
+        #endif
+        {
+            List_ACCESS(T, (*this), vp);
+            List_CONST_ACCESS(T, a, ap);
+            List_FOR_ALL((*this), i)
+            {
+                vp[i] = ap[i];
+            }
         }
     }
 }
@@ -191,13 +258,14 @@ Foam::List<T>::List(const UList<T>& lst, const labelUList& mapAddressing)
 :
     UList<T>(nullptr, mapAddressing.size())
 {
-    if (this->size_)
+    const label len = mapAddressing.size();
+
+    if (len)
     {
         alloc();
 
         List_ACCESS(T, (*this), vp);
 
-        const label len = (*this).size();
         for (label i=0; i < len; ++i)
         {
             vp[i] = lst[mapAddressing[i]];
@@ -220,7 +288,8 @@ Foam::List<T>::List(const FixedList<T, Size>& lst)
 :
     UList<T>(nullptr, Size)
 {
-    allocCopyList(lst);
+    alloc();
+    copyList(lst);
 }
 
 
@@ -229,7 +298,8 @@ Foam::List<T>::List(const PtrList<T>& lst)
 :
     UList<T>(nullptr, lst.size())
 {
-    allocCopyList(lst);
+    alloc();
+    copyList(lst);
 }
 
 
@@ -245,7 +315,8 @@ Foam::List<T>::List(const UIndirectList<T>& lst)
 :
     UList<T>(nullptr, lst.size())
 {
-    allocCopyList(lst);
+    alloc();
+    copyList(lst);
 }
 
 
@@ -254,7 +325,8 @@ Foam::List<T>::List(const BiIndirectList<T>& lst)
 :
     UList<T>(nullptr, lst.size())
 {
-    allocCopyList(lst);
+    alloc();
+    copyList(lst);
 }
 
 
@@ -329,7 +401,7 @@ void Foam::List<T>::setSize(const label newSize)
     {
         if (newSize > 0)
         {
-            T* nv = new T[label(newSize)];
+            T* nv = new T[newSize];
 
             const label overlap = min(this->size_, newSize);
 
@@ -367,7 +439,7 @@ void Foam::List<T>::setSize(const label newSize)
 template<class T>
 void Foam::List<T>::setSize(const label newSize, const T& val)
 {
-    const label oldSize = label(this->size_);
+    const label oldSize = this->size_;
     this->setSize(newSize);
 
     List_ACCESS(T, *this, vp);
@@ -474,28 +546,58 @@ void Foam::List<T>::operator=(const SLList<T>& lst)
 template<class T>
 void Foam::List<T>::operator=(const UIndirectList<T>& lst)
 {
-    reAlloc(lst.size());
-    copyList(lst);
+    const label len = lst.size();
+
+    reAlloc(len);
+
+    if (len)
+    {
+        List_ACCESS(T, (*this), vp);
+
+        for (label i=0; i<len; ++i)
+        {
+            vp[i] = lst[i];
+        }
+    }
 }
 
 
 template<class T>
 void Foam::List<T>::operator=(const BiIndirectList<T>& lst)
 {
-    reAlloc(lst.size());
-    copyList(lst);
+    const label len = lst.size();
+
+    reAlloc(len);
+
+    if (len)
+    {
+        List_ACCESS(T, (*this), vp);
+
+        for (label i=0; i<len; ++i)
+        {
+            vp[i] = lst[i];
+        }
+    }
 }
 
 
 template<class T>
 void Foam::List<T>::operator=(std::initializer_list<T> lst)
 {
-    reAlloc(lst.size());
+    const label len = lst.size();
+
+    reAlloc(len);
 
-    label i = 0;
-    for (const auto& val : lst)
+    if (len)
     {
-        this->operator[](i++) = val;
+        List_ACCESS(T, (*this), vp);
+
+        label i = 0;
+        for (const auto& val : lst)
+        {
+            vp[i] = val;
+            ++i;
+        }
     }
 }
 
diff --git a/src/OpenFOAM/containers/Lists/List/List.H b/src/OpenFOAM/containers/Lists/List/List.H
index ec6ea7c515..e27dffde08 100644
--- a/src/OpenFOAM/containers/Lists/List/List.H
+++ b/src/OpenFOAM/containers/Lists/List/List.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  | Copyright (C) 2017 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2017-2018 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -50,16 +50,12 @@ SourceFiles
 namespace Foam
 {
 
-// Forward declaration of classes
+// Forward declarations
 
 class Istream;
 class Ostream;
 
-// Forward declaration of friend functions and operators
 template<class T> class List;
-
-template<class T> Istream& operator>>(Istream& is, List<T>& L);
-
 template<class T, unsigned Size> class FixedList;
 template<class T> class PtrList;
 
@@ -75,8 +71,11 @@ template<class T> class IndirectList;
 template<class T> class UIndirectList;
 template<class T> class BiIndirectList;
 
+template<class T> Istream& operator>>(Istream& is, List<T>& L);
+
 typedef List<char> charList;
 
+
 /*---------------------------------------------------------------------------*\
                            Class List Declaration
 \*---------------------------------------------------------------------------*/
@@ -92,16 +91,12 @@ class List
         inline void alloc();
 
         //- Reallocate list storage to the given size
-        inline void reAlloc(const label s);
+        inline void reAlloc(const label len);
 
-        //- Copy list of given type
+        //- Copy list of given type.
         template<class List2>
         inline void copyList(const List2& lst);
 
-        //- Allocate storage and copy list of given type
-        template<class List2>
-        inline void allocCopyList(const List2& lst);
-
         //- Construct given begin/end iterators and number of elements
         //  Since the size is provided, the end iterator is actually ignored.
         template<class InputIterator>
@@ -109,7 +104,7 @@ class List
         (
             InputIterator begIter,
             InputIterator endIter,
-            const label s
+            const label len
         );
 
 
@@ -120,6 +115,44 @@ public:
         //- Return a null List
         inline static const List<T>& null();
 
+        //- Create from a list of a dissimilar type.
+        //  Eg, convert a list of ints to floats, vectors etc.
+        //  For example,
+        //  \code
+        //  auto vectors = List<vector>::createList
+        //  (
+        //      ints,
+        //      [](const int& val){ return vector(1.5*val, 0, 0); }
+        //  );
+        //
+        //  auto neg = labelList::createList
+        //  (
+        //      ints,
+        //      std::negate<label>()
+        //  );
+        //  auto labels = labelList::createList
+        //  (
+        //      ints,
+        //      toLabel<int>()
+        //  );
+        //  \endcode
+        template<class T2, class UnaryOperation>
+        static List<T> createList
+        (
+            const UList<T2>& input,
+            const UnaryOperation& op
+        );
+
+        //- Create from an iterator range (uses std::distance for the size).
+        //  The unary operation can be used to convert to other types.
+        template<class InputIterator, class UnaryOperation>
+        static List<T> createList
+        (
+            InputIterator begIter,
+            InputIterator endIter,
+            const UnaryOperation& op
+        );
+
 
     // Constructors
 
@@ -127,22 +160,19 @@ public:
         inline List();
 
         //- Construct with given size
-        explicit List(const label s);
+        explicit List(const label len);
 
         //- Construct with given size and value for all elements
-        List(const label s, const T& val);
+        List(const label len, const T& val);
 
         //- Construct with given size initializing all elements to zero
-        List(const label s, const zero);
+        List(const label len, const zero);
 
-        //- Copy constructor from list
+        //- Copy construct from list
         List(const List<T>& a);
 
-        //- Copy constructor from list containing another type.
-        //  This is primarily useful to convert a list of ints into floats,
-        //  for example.
-        template<class T2>
-        explicit List(const List<T2>& a);
+        //- Copy construct contents from list
+        explicit List(const UList<T>& a);
 
         //- Construct as copy or re-use as specified
         List(List<T>& a, bool reuse);
@@ -151,7 +181,7 @@ public:
         List(const UList<T>& lst, const labelUList& mapAddressing);
 
         //- Construct given begin/end iterators.
-        //  Uses std::distance to determine the size.
+        //  Uses std::distance for the size.
         template<class InputIterator>
         List(InputIterator begIter, InputIterator endIter);
 
diff --git a/src/OpenFOAM/containers/Lists/List/ListI.H b/src/OpenFOAM/containers/Lists/List/ListI.H
index b815a32d87..eb6eab8bd5 100644
--- a/src/OpenFOAM/containers/Lists/List/ListI.H
+++ b/src/OpenFOAM/containers/Lists/List/ListI.H
@@ -36,12 +36,12 @@ inline void Foam::List<T>::alloc()
 
 
 template<class T>
-inline void Foam::List<T>::reAlloc(const label s)
+inline void Foam::List<T>::reAlloc(const label len)
 {
-    if (this->size_ != s)
+    if (this->size_ != len)
     {
         clear();
-        this->size_ = s;
+        this->size_ = len;
         alloc();
     }
 }
@@ -51,24 +51,11 @@ template<class T>
 template<class List2>
 inline void Foam::List<T>::copyList(const List2& lst)
 {
-    if (this->size_)
-    {
-        forAll(*this, i)
-        {
-            this->operator[](i) = lst[i];
-        }
-    }
-}
+    const label len = this->size_;
 
-
-template<class T>
-template<class List2>
-inline void Foam::List<T>::allocCopyList(const List2& lst)
-{
-    if (this->size_)
+    for (label i=0; i<len; ++i)
     {
-        alloc();
-        copyList(lst);
+        this->operator[](i) = lst[i];
     }
 }
 
@@ -79,17 +66,17 @@ inline Foam::List<T>::List
 (
     InputIterator begIter,
     InputIterator endIter,
-    const label s
+    const label len
 )
 :
-    UList<T>(nullptr, s)
+    UList<T>(nullptr, len)
 {
     if (this->size_)
     {
         alloc();
 
         InputIterator iter = begIter;
-        for (label i = 0; i < s; ++i)
+        for (label i = 0; i < len; ++i)
         {
             this->operator[](i) = *iter;
             ++iter;
@@ -135,16 +122,16 @@ inline void Foam::List<T>::clear()
 
 
 template<class T>
-inline void Foam::List<T>::resize(const label newSize)
+inline void Foam::List<T>::resize(const label len)
 {
-    this->setSize(newSize);
+    this->setSize(len);
 }
 
 
 template<class T>
-inline void Foam::List<T>::resize(const label newSize, const T& val)
+inline void Foam::List<T>::resize(const label len, const T& val)
 {
-    this->setSize(newSize, val);
+    this->setSize(len, val);
 }
 
 
diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOps.C b/src/OpenFOAM/containers/Lists/ListOps/ListOps.C
index 762b7fe8d6..8f92bf5c5b 100644
--- a/src/OpenFOAM/containers/Lists/ListOps/ListOps.C
+++ b/src/OpenFOAM/containers/Lists/ListOps/ListOps.C
@@ -25,7 +25,6 @@ License
 
 #include "ListOps.H"
 
-
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 const Foam::labelList Foam::emptyLabelList;
diff --git a/src/OpenFOAM/db/Time/TimeIO.C b/src/OpenFOAM/db/Time/TimeIO.C
index 9379be5df9..f82f91a368 100644
--- a/src/OpenFOAM/db/Time/TimeIO.C
+++ b/src/OpenFOAM/db/Time/TimeIO.C
@@ -141,10 +141,10 @@ void Foam::Time::readDict()
         )
         {
             // Remove the old watches since destroying the file
-            fileNameList oldWatchedFiles(controlDict_.watchIndices());
+            fileNameList oldWatchedFiles(controlDict_.watchIndices().size());
             forAllReverse(controlDict_.watchIndices(), i)
             {
-                label watchi = controlDict_.watchIndices()[i];
+                const label watchi = controlDict_.watchIndices()[i];
                 oldWatchedFiles[i] = fileHandler().getFile(watchi);
                 fileHandler().removeWatch(watchi);
             }
diff --git a/src/OpenFOAM/primitives/ints/label/label.H b/src/OpenFOAM/primitives/ints/label/label.H
index 11a862fd7c..013a889da6 100644
--- a/src/OpenFOAM/primitives/ints/label/label.H
+++ b/src/OpenFOAM/primitives/ints/label/label.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2018 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -120,6 +120,40 @@ inline label component(const label l, const direction)
     return l;
 }
 
+
+/*---------------------------------------------------------------------------*\
+                          Struct toLabel Declaration
+\*---------------------------------------------------------------------------*/
+
+//- Conversion to label structure
+template<class Type> struct toLabel {};
+
+//- Convert (likely promote) from int32_t to label
+template<>
+struct toLabel<int32_t>
+{
+    constexpr label operator()(const int32_t& val) const noexcept
+    {
+        return val;
+    }
+};
+
+
+//- Convert (possibly truncate) from int64_t to label
+template<>
+struct toLabel<int64_t>
+{
+    constexpr label operator()(const int64_t& val) const noexcept
+    {
+        #if WM_LABEL_SIZE == 32
+        return label(val);
+        #elif WM_LABEL_SIZE == 64
+        return val;
+        #endif
+    }
+};
+
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace Foam
-- 
GitLab