From 4965ea49883b7bd103d4bd1416988bcc57ea4365 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Sat, 10 Nov 2018 17:20:32 +0100
Subject: [PATCH] ENH: simplify/extend objectRegistry code with templated
 predicates

- replace explicit use of wordRe, wordRes, wordHashSet as filters
  with a MatchPredicate.

- support filtering by class based on <Type> or predicates
---
 .../test/objectRegistry/Test-objectRegistry.C |  47 ++------
 .../db/objectRegistry/objectRegistry.C        |  47 +-------
 .../db/objectRegistry/objectRegistry.H        | 108 +++++++++--------
 .../objectRegistry/objectRegistryTemplates.C  | 111 ++++++++++++++----
 4 files changed, 161 insertions(+), 152 deletions(-)

diff --git a/applications/test/objectRegistry/Test-objectRegistry.C b/applications/test/objectRegistry/Test-objectRegistry.C
index 73e9f193d39..ba56f115be6 100644
--- a/applications/test/objectRegistry/Test-objectRegistry.C
+++ b/applications/test/objectRegistry/Test-objectRegistry.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2018 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -34,8 +34,8 @@ Description
 #include "Time.H"
 #include "polyMesh.H"
 #include "IOstreams.H"
+#include "FlatOutput.H"
 #include "objectRegistry.H"
-#include "hashedWordList.H"
 
 using namespace Foam;
 
@@ -45,22 +45,6 @@ using namespace Foam;
 bool recursive = false;
 
 
-template<class Type>
-Foam::Ostream& printList(Foam::Ostream& os, const UList<Type>& list)
-{
-    // list with out any linebreaks
-    os  << '(';
-    forAll(list, i)
-    {
-        if (i) os << ' ';
-        os  << list[i];
-    }
-    os  << ')';
-
-    return os;
-}
-
-
 void printRegistry
 (
     Foam::Ostream& os,
@@ -76,8 +60,8 @@ void printRegistry
     Foam::label indent
 )
 {
-    wordList names = obr.sortedNames();
-    hashedWordList regs = obr.sortedNames<objectRegistry>();
+    wordList names(obr.sortedNames());
+    wordList regs(obr.sortedNames<objectRegistry>());
 
     std::string prefix;
     for (label i=indent; i; --i)
@@ -88,23 +72,13 @@ void printRegistry
     os  << '#' << prefix.c_str() << obr.name()
         << " parent:" << obr.parent().name() << nl;
 
-    // all names
-    {
-        os  << ' ' << prefix.c_str() << "objects: ";
-        printList(os, names) << nl;
-    }
+    os  << ' ' << prefix.c_str() << "objects: " << flatOutput(names) << nl;
+    os  << ' ' << prefix.c_str() << "registries: " << flatOutput(regs) << nl;
 
-    // sub-registry names
-    {
-        os  << ' ' << prefix.c_str() << "registries: ";
-        printList(os, regs) << nl;
-    }
 
     // Print, but skip expansion of sub-registries for now
-    forAll(names, i)
+    for (const word& name : names)
     {
-        const word& name = names[i];
-
         os  << (regs.found(name) ? '-' : ' ')
             << prefix.c_str() << name << " => " << obr[name]->type() << nl;
     }
@@ -115,9 +89,8 @@ void printRegistry
     os  << '\n';
 
     // Now descend into the sub-registries
-    forAll(regs, i)
+    for (const word& name : regs)
     {
-        const word& name = regs[i];
         const objectRegistry& next = obr.lookupObject<objectRegistry>
         (
             name,
@@ -240,8 +213,8 @@ int main(int argc, char *argv[])
         );
     }
 
-    Info<< "after adding some entries, top-level now contains: ";
-    printList(Info, db.names()) << endl;
+    Info<< "after adding some entries, top-level now contains: "
+        << flatOutput(db.names()) << endl;
 
     Info<<"## Now attempt to add a few more entries ##" << nl;
 
diff --git a/src/OpenFOAM/db/objectRegistry/objectRegistry.C b/src/OpenFOAM/db/objectRegistry/objectRegistry.C
index b91a94d228d..d2b0a1a2c68 100644
--- a/src/OpenFOAM/db/objectRegistry/objectRegistry.C
+++ b/src/OpenFOAM/db/objectRegistry/objectRegistry.C
@@ -111,27 +111,6 @@ Foam::HashTable<Foam::wordHashSet> Foam::objectRegistry::classes() const
 }
 
 
-Foam::HashTable<Foam::wordHashSet>
-Foam::objectRegistry::classes(const wordRe& matchName) const
-{
-    return classesImpl(*this, matchName);
-}
-
-
-Foam::HashTable<Foam::wordHashSet>
-Foam::objectRegistry::classes(const wordRes& matchName) const
-{
-    return classesImpl(*this, matchName);
-}
-
-
-Foam::HashTable<Foam::wordHashSet>
-Foam::objectRegistry::classes(const wordHashSet& matchName) const
-{
-    return classesImpl(*this, matchName);
-}
-
-
 Foam::wordList Foam::objectRegistry::names() const
 {
     return HashTable<regIOobject*>::toc();
@@ -144,31 +123,17 @@ Foam::wordList Foam::objectRegistry::sortedNames() const
 }
 
 
-Foam::wordList Foam::objectRegistry::names(const word& clsName) const
+Foam::wordList Foam::objectRegistry::names(const char* clsName) const
 {
-    wordList objNames(size());
-
-    label count=0;
-    for (const_iterator iter = cbegin(); iter != cend(); ++iter)
-    {
-        if (iter()->type() == clsName)
-        {
-            objNames[count++] = iter.key();
-        }
-    }
-
-    objNames.setSize(count);
-
-    return objNames;
+    // No nullptr check - only called with string literals
+    return names(static_cast<word>(clsName));
 }
 
 
-Foam::wordList Foam::objectRegistry::sortedNames(const word& clsName) const
+Foam::wordList Foam::objectRegistry::sortedNames(const char* clsName) const
 {
-    wordList objNames = names(clsName);
-    Foam::sort(objNames);
-
-    return objNames;
+    // No nullptr check - only called with string literals
+    return sortedNames(static_cast<word>(clsName));
 }
 
 
diff --git a/src/OpenFOAM/db/objectRegistry/objectRegistry.H b/src/OpenFOAM/db/objectRegistry/objectRegistry.H
index 8a92fbd26e5..30c03f8e31b 100644
--- a/src/OpenFOAM/db/objectRegistry/objectRegistry.H
+++ b/src/OpenFOAM/db/objectRegistry/objectRegistry.H
@@ -89,6 +89,16 @@ class objectRegistry
             const MatchPredicate& matchName
         );
 
+        //- Templated implementation for names(), sortedNames()
+        template<class MatchPredicate1, class MatchPredicate2>
+        static wordList namesImpl
+        (
+            const objectRegistry& list,
+            const MatchPredicate1& matchClass,
+            const MatchPredicate2& matchName,
+            const bool doSort
+        );
+
         //- Templated implementation for names(), sortedNames()
         template<class Type, class MatchPredicate>
         static wordList namesTypeImpl
@@ -157,90 +167,86 @@ public:
         //  Behaviour and usage as per IOobjectList::classes
         HashTable<wordHashSet> classes() const;
 
-        //- A summary hash of classes used and their associated object names
-        //- restricted to objects with names that satisfy the input matcher
-        HashTable<wordHashSet> classes(const wordRe& matchName) const;
-
-        //- A summary hash of classes used and their associated object names
-        //- restricted to objects with names that satisfy the input matcher
-        HashTable<wordHashSet> classes(const wordRes& matchName) const;
-
-        //- A summary hash of classes used and their associated object names
-        //- restricted to objects with names that satisfy the input matcher
-        HashTable<wordHashSet> classes(const wordHashSet& matchName) const;
+        //- A summary hash of classes used and their associated object names,
+        //- restricted to objects that have a matching object name.
+        template<class MatchPredicate>
+        HashTable<wordHashSet> classes(const MatchPredicate& matchName) const;
 
 
     // Summary of names
 
-        //- The names of the objects
+        //- The names of all objects
         wordList names() const;
 
-        //- The names of objects with the given class
-        wordList names(const word& clsName) const;
+        //- The names of objects with the given class name.
+        //  \note uses the class type() method
+        wordList names(const char* clsName) const;
 
-        //- The names of objects with a class satisfying \c isA\<Type\>.
-        //
-        //  \note If \a Type is \c void, no isA check is used (always true).
-        template<class Type>
-        wordList names() const;
+        //- The names of objects with a matching class name
+        //  \note uses the class type() method
+        template<class MatchPredicate>
+        wordList names(const MatchPredicate& matchClass) const;
 
-        //- The names of objects with a class satisfying \c isA\<Type\>
-        //- that also have a name satisfying the input matcher
-        //
-        //  \note If \a Type is \c void, no isA check is used (always true).
-        template<class Type>
-        wordList names(const wordRe& matchName) const;
+        //- The names of objects with a matching class name
+        //- that also have a matching object name.
+        //  \note uses the class type() method
+        template<class MatchPredicate1, class MatchPredicate2>
+        wordList names
+        (
+            const MatchPredicate1& matchClass,
+            const MatchPredicate2& matchName
+        ) const;
 
-        //- The names of objects with a class satisfying \c isA\<Type\>
-        //- that also have a name satisfying the input matcher
+        //- The names of objects with a class satisfying \c isA\<Type\>.
         //
         //  \note If \a Type is \c void, no isA check is used (always true).
         template<class Type>
-        wordList names(const wordRes& matchName) const;
+        wordList names() const;
 
         //- The names of objects with a class satisfying \c isA\<Type\>
-        //- that also have a name satisfying the input matcher
+        //- that also have a matching object name.
         //
         //  \note If \a Type is \c void, no isA check is used (always true).
-        template<class Type>
-        wordList names(const wordHashSet& matchName) const;
+        template<class Type, class MatchPredicate>
+        wordList names(const MatchPredicate& matchName) const;
 
 
     // Summary of names (sorted)
 
-        //- The sorted names of the objects
+        //- The sorted names of all objects
         wordList sortedNames() const;
 
-        //- The sorted names of objects with the given class
-        wordList sortedNames(const word& clsName) const;
+        //- The sorted names of objects with the given class name.
+        //  \note uses the class type() method
+        wordList sortedNames(const char* clsName) const;
 
-        //- The sorted names of objects with a class satisfying \c isA\<Type\>
-        //- that also have a name satisfying the input matcher
-        //
-        //  \note If \a Type is \c void, no isA check is used (always true).
-        template<class Type>
-        wordList sortedNames() const;
+        //- The sorted names objects with a matching class name
+        //  \note uses the class type() method
+        template<class MatchPredicate>
+        wordList sortedNames(const MatchPredicate& matchClass) const;
 
-        //- The sorted names of objects with a class satisfying \c isA\<Type\>
-        //- that also have a name satisfying the input matcher
-        //
-        //  \note If \a Type is \c void, no isA check is used (always true).
-        template<class Type>
-        wordList sortedNames(const wordRe& matchName) const;
+        //- The sorted names of objects with a matching class name
+        //- that also have a matching object name.
+        //  \note uses the class type() method
+        template<class MatchPredicate1, class MatchPredicate2>
+        wordList sortedNames
+        (
+            const MatchPredicate1& matchClass,
+            const MatchPredicate2& matchName
+        ) const;
 
         //- The sorted names of objects with a class satisfying \c isA\<Type\>
-        //- that also have a name satisfying the input matcher
         //
         //  \note If \a Type is \c void, no isA check is used (always true).
         template<class Type>
-        wordList sortedNames(const wordRes& matchName) const;
+        wordList sortedNames() const;
 
         //- The sorted names of objects with a class satisfying \c isA\<Type\>
-        //- that also have a name satisfying the input matcher
+        //- that also have a matching object name.
         //
         //  \note If \a Type is \c void, no isA check is used (always true).
-        template<class Type>
-        wordList sortedNames(const wordHashSet& matchName) const;
+        template<class Type, class MatchPredicate>
+        wordList sortedNames(const MatchPredicate& matchName) const;
 
 
     // Lookup
diff --git a/src/OpenFOAM/db/objectRegistry/objectRegistryTemplates.C b/src/OpenFOAM/db/objectRegistry/objectRegistryTemplates.C
index 20740e07d05..c63ff76acec 100644
--- a/src/OpenFOAM/db/objectRegistry/objectRegistryTemplates.C
+++ b/src/OpenFOAM/db/objectRegistry/objectRegistryTemplates.C
@@ -42,10 +42,12 @@ Foam::HashTable<Foam::wordHashSet> Foam::objectRegistry::classesImpl
     // Summary (key,val) = (class-name, object-names)
     forAllConstIters(list, iter)
     {
-        if (matchName(iter.key()))
+        const regIOobject* obj = iter.object();
+
+        if (matchName(obj->name()))
         {
             // Create entry (if needed) and insert
-            summary(iter.object()->type()).insert(iter.key());
+            summary(iter.object()->type()).insert(obj->name());
         }
     }
 
@@ -53,6 +55,41 @@ Foam::HashTable<Foam::wordHashSet> Foam::objectRegistry::classesImpl
 }
 
 
+// Templated implementation for names(), sortedNames()
+template<class MatchPredicate1, class MatchPredicate2>
+Foam::wordList Foam::objectRegistry::namesImpl
+(
+    const objectRegistry& list,
+    const MatchPredicate1& matchClass,
+    const MatchPredicate2& matchName,
+    const bool doSort
+)
+{
+    wordList objNames(list.size());
+
+    label count=0;
+    forAllConstIters(list, iter)
+    {
+        const regIOobject* obj = iter.object();
+
+        if (matchClass(obj->type()) && matchName(obj->name()))
+        {
+            objNames[count] = obj->name();
+            ++count;
+        }
+    }
+
+    objNames.resize(count);
+
+    if (doSort)
+    {
+        Foam::sort(objNames);
+    }
+
+    return objNames;
+}
+
+
 // Templated implementation for names(), sortedNames()
 template<class Type, class MatchPredicate>
 Foam::wordList Foam::objectRegistry::namesTypeImpl
@@ -75,7 +112,7 @@ Foam::wordList Foam::objectRegistry::namesTypeImpl
          && matchName(obj->name())
         )
         {
-            objNames[count] = iter()->name();
+            objNames[count] = obj->name();
             ++count;
         }
     }
@@ -93,59 +130,87 @@ Foam::wordList Foam::objectRegistry::namesTypeImpl
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-template<class Type>
-Foam::wordList Foam::objectRegistry::names() const
+template<class MatchPredicate>
+Foam::HashTable<Foam::wordHashSet>
+Foam::objectRegistry::classes
+(
+    const MatchPredicate& matchName
+) const
 {
-    return namesTypeImpl<Type>(*this, predicates::always(), false);
+    return classesImpl(*this, matchName);
 }
 
 
-template<class Type>
-Foam::wordList Foam::objectRegistry::names(const wordRe& matchName) const
+template<class MatchPredicate>
+Foam::wordList Foam::objectRegistry::names
+(
+    const MatchPredicate& matchClass
+) const
 {
-    return namesTypeImpl<Type>(*this, matchName, false);
+    return namesImpl(*this, matchClass, predicates::always(), false);
 }
 
 
-template<class Type>
-Foam::wordList Foam::objectRegistry::names(const wordRes& matchName) const
+template<class MatchPredicate1, class MatchPredicate2>
+Foam::wordList Foam::objectRegistry::names
+(
+    const MatchPredicate1& matchClass,
+    const MatchPredicate2& matchName
+) const
 {
-    return namesTypeImpl<Type>(*this, matchName, false);
+    return namesImpl(*this, matchClass, matchName, false);
 }
 
 
 template<class Type>
-Foam::wordList Foam::objectRegistry::names(const wordHashSet& matchName) const
+Foam::wordList Foam::objectRegistry::names() const
+{
+    return namesTypeImpl<Type>(*this, predicates::always(), false);
+}
+
+
+template<class Type, class MatchPredicate>
+Foam::wordList Foam::objectRegistry::names
+(
+    const MatchPredicate& matchName
+) const
 {
     return namesTypeImpl<Type>(*this, matchName, false);
 }
 
 
-template<class Type>
-Foam::wordList Foam::objectRegistry::sortedNames() const
+template<class MatchPredicate>
+Foam::wordList Foam::objectRegistry::sortedNames
+(
+    const MatchPredicate& matchClass
+) const
 {
-    return namesTypeImpl<Type>(*this, predicates::always(), true);
+    return namesImpl(*this, matchClass, predicates::always(), true);
 }
 
 
-template<class Type>
-Foam::wordList Foam::objectRegistry::sortedNames(const wordRe& matchName) const
+template<class MatchPredicate1, class MatchPredicate2>
+Foam::wordList Foam::objectRegistry::sortedNames
+(
+    const MatchPredicate1& matchClass,
+    const MatchPredicate2& matchName
+) const
 {
-    return namesTypeImpl<Type>(*this, matchName, true);
+    return namesImpl(*this, matchClass, matchName, true);
 }
 
 
 template<class Type>
-Foam::wordList Foam::objectRegistry::sortedNames(const wordRes& matchName) const
+Foam::wordList Foam::objectRegistry::sortedNames() const
 {
-    return namesTypeImpl<Type>(*this, matchName, true);
+    return namesTypeImpl<Type>(*this, predicates::always(), true);
 }
 
 
-template<class Type>
+template<class Type, class MatchPredicate>
 Foam::wordList Foam::objectRegistry::sortedNames
 (
-    const wordHashSet& matchName
+    const MatchPredicate& matchName
 ) const
 {
     return namesTypeImpl<Type>(*this, matchName, true);
-- 
GitLab