From b08dadff62b52f56665628a6b3a9c8d9e6a9a75c Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@Germany>
Date: Sun, 18 Dec 2016 20:09:58 +0100
Subject: [PATCH] ENH: initializer list constructor for fileName

This slightly more convenient when working with char[] input:

     fileName file1{ "path", "name", "to", "file.ext" };
vs.  fileName file1 = fileName(path)/"name"/"to"/"file.ext";

But is a bit more efficient since it avoid most of the intermediate
copying and resizing incurred by the '/' operator.
---
 applications/test/fileName/Test-fileName.C    | 87 +++++++++++++++++--
 .../primitives/strings/fileName/fileName.C    | 41 ++++++++-
 .../primitives/strings/fileName/fileName.H    |  8 +-
 3 files changed, 123 insertions(+), 13 deletions(-)

diff --git a/applications/test/fileName/Test-fileName.C b/applications/test/fileName/Test-fileName.C
index e214e98813f..de8751c7b01 100644
--- a/applications/test/fileName/Test-fileName.C
+++ b/applications/test/fileName/Test-fileName.C
@@ -29,26 +29,98 @@ Description
 
 \*---------------------------------------------------------------------------*/
 
+#include "argList.H"
 #include "fileName.H"
 #include "SubList.H"
+#include "DynamicList.H"
 #include "IOobject.H"
 #include "IOstreams.H"
 #include "OSspecific.H"
 #include "POSIX.H"
+#include "etcFiles.H"
 
 using namespace Foam;
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 // Main program:
 
-int main()
+int main(int argc, char *argv[])
 {
-    wordList wrdList(5);
-    wrdList[0] = "hello";
-    wrdList[1] = "hello1";
-    wrdList[2] = "hello2";
-    wrdList[3] = "hello3";
-    wrdList[4] = "hello4.hmm";
+    argList::noParallel();
+    argList::addBoolOption("construct", "test constructors");
+    argList::addBoolOption("default", "reinstate default tests");
+    argList::addNote("runs default tests or specified ones only");
+
+    #include "setRootCase.H"
+
+    // Run default tests, unless only specific tests are requested
+    const bool defaultTests =
+        args.optionFound("default") || args.options().empty();
+
+    if (args.optionFound("construct"))
+    {
+        Info<< "From initializer_list<word> = ";
+        fileName file1
+        {
+            "hello",
+            "hello1",
+            "hello2",
+            "hello3",
+            "hello4.hmm"
+        };
+
+        Info<< file1 << nl;
+
+        Info<< "From initializer_list<fileName> = ";
+        fileName file2
+        {
+            file1,
+            "some",
+            "more/things.hmm"
+        };
+
+        Info<< file2 << nl;
+
+
+        Info<< "From initializer_list<fileName> with nesting = ";
+        fileName file3
+        {
+            std::string("ffO"),
+            "some",
+            "more/things.hmm"
+        };
+        Info<< file3 << nl;
+
+        DynamicList<word> base
+        {
+            "hello",
+            "hello1"
+        };
+
+        fileName file4
+        {
+            "some",
+            file3,
+            "more/things.hmm",
+            file1
+        };
+        Info<< "All ==> " << file4 << nl;
+    }
+
+
+    if (!defaultTests)
+    {
+        return 0;
+    }
+
+    DynamicList<word> wrdList
+    {
+        "hello",
+        "hello1",
+        "hello2",
+        "hello3",
+        "hello4.hmm"
+    };
 
     fileName pathName(wrdList);
 
@@ -191,7 +263,6 @@ int main()
     }
 
 
-
     // test findEtcFile
     Info<< "\n\nfindEtcFile tests:" << nl
         << " controlDict => " << findEtcFile("controlDict") << nl
diff --git a/src/OpenFOAM/primitives/strings/fileName/fileName.C b/src/OpenFOAM/primitives/strings/fileName/fileName.C
index 2186c5f1713..7110bdf2f62 100644
--- a/src/OpenFOAM/primitives/strings/fileName/fileName.C
+++ b/src/OpenFOAM/primitives/strings/fileName/fileName.C
@@ -37,11 +37,46 @@ const Foam::fileName Foam::fileName::null;
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-Foam::fileName::fileName(const wordList& lst)
+Foam::fileName::fileName(const UList<word>& lst)
 {
-    forAll(lst, elemI)
+    // Estimate overall size
+    size_type sz = lst.size();
+    for (const word& item : lst)
     {
-        operator=((*this)/lst[elemI]);
+        sz += item.size();
+    }
+    reserve(sz);
+
+    sz = 0;
+    for (const word& item : lst)
+    {
+        if (item.size())
+        {
+            if (sz++) operator+=('/');
+            operator+=(item);
+        }
+    }
+}
+
+
+Foam::fileName::fileName(std::initializer_list<word> lst)
+{
+    // Estimate overall size
+    size_type sz = lst.size();
+    for (const word& item : lst)
+    {
+        sz += item.size();
+    }
+    reserve(sz);
+
+    sz = 0;
+    for (const word& item : lst)
+    {
+        if (item.size())
+        {
+            if (sz++) operator+=('/');
+            operator+=(item);
+        }
     }
 }
 
diff --git a/src/OpenFOAM/primitives/strings/fileName/fileName.H b/src/OpenFOAM/primitives/strings/fileName/fileName.H
index 18198ea0fc3..cc49f365e4f 100644
--- a/src/OpenFOAM/primitives/strings/fileName/fileName.H
+++ b/src/OpenFOAM/primitives/strings/fileName/fileName.H
@@ -53,10 +53,10 @@ namespace Foam
 {
 
 template<class T> class List;
+template<class T> class UList;
 typedef List<word> wordList;
 
 // Forward declaration of friend functions and operators
-
 class fileName;
 
 Istream& operator>>(Istream&, fileName&);
@@ -119,7 +119,11 @@ public:
         inline fileName(const char*, const bool doStripInvalid=true);
 
         //- Construct by concatenating elements of wordList separated by '/'
-        explicit fileName(const wordList&);
+        explicit fileName(const UList<word>&);
+
+        //- Construct by concatenating words separated by '/'
+        explicit fileName(std::initializer_list<word>);
+
 
         //- Construct from Istream
         fileName(Istream&);
-- 
GitLab