From 4fc6ec1d1d1c6cd4a537de21e34caa23255f8450 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Thu, 15 Jul 2021 01:05:30 +0200
Subject: [PATCH] ENH: define singleton-style lookups for runTime selection,
 alias handling

- this makes the lookup and use of tables slightly cleaner and
  provides a hook for update (compat) messages

  The singleton-style method returns the function pointer directly,
  or nullptr on not-found.

  NEW access method (mnemonic: 'ctor' prefix for constructors)

  ```
  auto* ctorPtr = dictionaryConstructorTable(modelType);

  if (!ctorPtr)
  {
      ...
  }

  return autoPtr<myModel>(ctorPtr(dict, ...));
  ```

  OLD method, which also still works, but without any compat handling:

  ```
  auto ctorIter = dictionaryConstructorTablePtr_->cfind(modelType);

  if (!ctorIter.found())
  {
      ...
  }

  return autoPtr<myModel>(ctorIter()(dict, ...));
  ```
---
 .../construction/addToRunTimeSelectionTable.H |  31 ++++++
 .../construction/runTimeSelectionTables.H     | 102 +++++++++++++++++-
 .../addToMemberFunctionSelectionTable.H       |  33 ++++++
 .../memberFunctionSelectionTables.H           |  22 +++-
 4 files changed, 184 insertions(+), 4 deletions(-)

diff --git a/src/OpenFOAM/db/runTimeSelection/construction/addToRunTimeSelectionTable.H b/src/OpenFOAM/db/runTimeSelection/construction/addToRunTimeSelectionTable.H
index dc839d6dab3..885c8bcab40 100644
--- a/src/OpenFOAM/db/runTimeSelection/construction/addToRunTimeSelectionTable.H
+++ b/src/OpenFOAM/db/runTimeSelection/construction/addToRunTimeSelectionTable.H
@@ -76,6 +76,16 @@ Note
         baseType##Table_##lookupName##_(#lookupName)
 
 
+//- Add lookup alias for runTime selection
+#define addAliasToRunTimeSelectionTable\
+(baseType,thisType,argNames,lookup,other,ver)                                  \
+                                                                               \
+    /* Add thisType constructor function to the table, find by lookup */       \
+    baseType::addAlias##argNames##ConstructorToTable<thisType>                 \
+        add##thisType##argNames##ConstructorTo##baseType##Table_               \
+        ##lookup##_##other##_(#lookup,#other,ver)
+
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 //- Add to construction table with typeName as the key.
@@ -99,6 +109,16 @@ Note
         baseType##Table_##lookupName##_(#lookupName)
 
 
+//- Add lookup alias for for runTime selection
+#define addAliasTemplateToRunTimeSelectionTable\
+(baseType,thisType,Targ,argNames,lookup,other,ver)                             \
+                                                                               \
+    /* Add thisType constructor function to the table, find by lookup */       \
+    baseType::addAlias##argNames##ConstructorToTable<thisType<Targ>>           \
+        add##thisType##Targs##argNames##ConstructorTo##baseType##Table_        \
+        ##lookup##_##other##_(#lookup,#other,ver)
+
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 //- Add to construction table with typeName as the key.
@@ -122,6 +142,17 @@ Note
         baseType##Targ##Table_##lookupName##_(#lookupName)
 
 
+//- Add lookup alias for for runTime selection
+//  Use when baseType requires the Targ template argument as well
+#define addAliasTemplatedToRunTimeSelectionTable\
+(baseType,thisType,Targ,argNames,lookup,other,ver)                             \
+                                                                               \
+    /* Add the thisType constructor function to the table, find by lookup */   \
+    baseType<Targ>::add##argNames##ConstructorToTable<thisType<Targ>>          \
+        add##thisType##Targ##argNames##ConstructorTo##baseType##Targ## \
+        Table_##lookup##_##other##_(#lookup,#other,ver)
+
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #endif
diff --git a/src/OpenFOAM/db/runTimeSelection/construction/runTimeSelectionTables.H b/src/OpenFOAM/db/runTimeSelection/construction/runTimeSelectionTables.H
index 0fa16f0e6f3..976bd6e7df9 100644
--- a/src/OpenFOAM/db/runTimeSelection/construction/runTimeSelectionTables.H
+++ b/src/OpenFOAM/db/runTimeSelection/construction/runTimeSelectionTables.H
@@ -40,6 +40,9 @@ Description
 #ifndef runTimeSelectionTables_H
 #define runTimeSelectionTables_H
 
+#include <memory>   // For std::unique_ptr
+#include <utility>  // For std::pair
+
 #include "autoPtr.H"
 #include "HashTable.H"
 
@@ -61,11 +64,28 @@ Description
         ::Foam::string::hasher                                                 \
     > prefix##TableType;                                                       \
                                                                                \
+    /* Lookup aliases for constructors */                                      \
+    typedef ::Foam::HashTable                                                  \
+    <                                                                          \
+        std::pair<::Foam::word,int>,                                           \
+        ::Foam::word,                                                          \
+        ::Foam::string::hasher                                                 \
+    > prefix##CompatTableType;                                                 \
+                                                                               \
     /* Table singleton (storage) */                                            \
     static prefix##TableType* prefix##TablePtr_;                               \
                                                                                \
+    /* Lookup aliases singleton (storage) */                                   \
+    static std::unique_ptr<prefix##CompatTableType> prefix##CompatTablePtr_;   \
+                                                                               \
+    /* Aliases singleton (access) */                                           \
+    static prefix##CompatTableType& prefix##CompatTable();                     \
+                                                                               \
     /* Table construct/destruct helper */                                      \
-    static void prefix##TablePtr_construct(bool load)
+    static void prefix##TablePtr_construct(bool load);                         \
+                                                                               \
+    /* Lookup function pointer from singleton, nullptr if not found */         \
+    static prefix##Ptr prefix##Table(const ::Foam::word& k)
 
 
 // Not used directly: storage and helper methods for runtime tables
@@ -74,6 +94,20 @@ Description
     /* Define table singleton (storage) */                                     \
     Tspecialize prefix##TableType* prefix##TablePtr_(nullptr);                 \
                                                                                \
+    /* Define aliases singleton (storage) */                                   \
+    Tspecialize                                                                \
+    std::unique_ptr<prefix##CompatTableType> prefix##CompatTablePtr_(nullptr); \
+                                                                               \
+    /* Define table singleton (access) for aliases */                          \
+    Tspecialize prefix##CompatTableType& prefix##CompatTable()                 \
+    {                                                                          \
+        if (!prefix##CompatTablePtr_)                                          \
+        {                                                                      \
+            prefix##CompatTablePtr_.reset(new prefix##CompatTableType(16));    \
+        }                                                                      \
+        return *(prefix##CompatTablePtr_);                                     \
+    }                                                                          \
+                                                                               \
     /* Table construct/destruct helper */                                      \
     Tspecialize void prefix##TablePtr_construct(bool load)                     \
     {                                                                          \
@@ -90,8 +124,42 @@ Description
         {                                                                      \
             delete prefix##TablePtr_;                                          \
             prefix##TablePtr_ = nullptr;                                       \
+            prefix##CompatTablePtr_.reset(nullptr);                            \
             constructed = false;                                               \
         }                                                                      \
+    }                                                                          \
+                                                                               \
+    /* Define lookup function pointer (singleton) */                           \
+    Tspecialize prefix##Ptr prefix##Table(const ::Foam::word& k)               \
+    {                                                                          \
+        if (prefix##TablePtr_)                                                 \
+        {                                                                      \
+            const auto& tbl = *prefix##TablePtr_;                              \
+            auto iter = tbl.cfind(k);                                          \
+            if (!iter.found() && prefix##CompatTablePtr_)                      \
+            {                                                                  \
+                const auto altIter = prefix##CompatTablePtr_->cfind(k);        \
+                if (altIter.found())                                           \
+                {                                                              \
+                    const auto& alt = altIter.val();  /* <word,int> */         \
+                    iter = tbl.cfind(alt.first);                               \
+                    if (::Foam::error::warnAboutAge(alt.second))               \
+                    {                                                          \
+                        std::cerr                                              \
+                            << "Using [v" << alt.second << "] '" << k          \
+                            << "' instead of '" << alt.first                   \
+                            << " in runtime selection table: "                 \
+                            << #baseType << '\n' << std::endl;                 \
+                        ::Foam::error::warnAboutAge("lookup", alt.second);     \
+                    }                                                          \
+                }                                                              \
+            }                                                                  \
+            if (iter.found())                                                  \
+            {                                                                  \
+                return iter.val();                                             \
+            }                                                                  \
+        }                                                                      \
+        return nullptr;                                                        \
     }
 
 
@@ -109,6 +177,22 @@ Description
     declareRunTimeSelectionTableBase(                                          \
         ptrWrapper<baseType>, argNames##Constructor, argList);                 \
                                                                                \
+    /* Helper to add compatibility/alias for runtime selection table */        \
+    template<class baseType##Type>                                             \
+    struct addAlias##argNames##ConstructorToTable                              \
+    {                                                                          \
+        explicit addAlias##argNames##ConstructorToTable                        \
+        (                                                                      \
+            const ::Foam::word& k,                                             \
+            const ::Foam::word& alias,                                         \
+            const int ver                                                      \
+        )                                                                      \
+        {                                                                      \
+            argNames##ConstructorCompatTable()                                 \
+                .set(alias, std::pair<::Foam::word,int>(k,ver));               \
+        }                                                                      \
+    };                                                                         \
+                                                                               \
     /* Helper to add constructor from argList to table */                      \
     template<class baseType##Type>                                             \
     struct add##argNames##ConstructorToTable                                   \
@@ -191,6 +275,22 @@ Description
     declareRunTimeSelectionTableBase(                                          \
         ptrWrapper<baseType>,argNames##Constructor,argList);                   \
                                                                                \
+    /* Helper to add compatibility/alias for runtime selection table */        \
+    template<class baseType##Type>                                             \
+    struct addAlias##argNames##ConstructorToTable                              \
+    {                                                                          \
+        explicit addAlias##argNames##ConstructorToTable                        \
+        (                                                                      \
+            const ::Foam::word& k,                                             \
+            const ::Foam::word& alias,                                         \
+            const int ver                                                      \
+        )                                                                      \
+        {                                                                      \
+            argNames##ConstructorCompatTable()                                 \
+                .set(alias, std::pair<::Foam::word,int>(k,ver));               \
+        }                                                                      \
+    };                                                                         \
+                                                                               \
     /* Helper to add constructor from argList to table */                      \
     template<class baseType##Type>                                             \
     struct add##argNames##ConstructorToTable                                   \
diff --git a/src/OpenFOAM/db/runTimeSelection/memberFunctions/addToMemberFunctionSelectionTable.H b/src/OpenFOAM/db/runTimeSelection/memberFunctions/addToMemberFunctionSelectionTable.H
index 1fc559276f2..4bd87c3fe43 100644
--- a/src/OpenFOAM/db/runTimeSelection/memberFunctions/addToMemberFunctionSelectionTable.H
+++ b/src/OpenFOAM/db/runTimeSelection/memberFunctions/addToMemberFunctionSelectionTable.H
@@ -60,6 +60,16 @@ Note
         baseType##Table_##lookupName##_(#lookupName)
 
 
+//- Add lookup alias for runTime member selection.
+#define addAliasToMemberFunctionSelectionTable\
+(baseType,thisType,funcName,argNames,lookup,other,ver)                         \
+                                                                               \
+    /* Add thisType funcName to the table, find by lookup name */              \
+    baseType::addAlias##funcName##argNames##MemberFunctionToTable<thisType>    \
+        add##thisType##funcName##argNames##MemberFunctionTo##baseType##Table_  \
+        ##lookup##_##other##_(#lookup,#other,ver)
+
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 //- Add to hash-table of functions with typeName as the key.
@@ -84,6 +94,19 @@ Note
         baseType##Table_##lookupName##_(#lookupName)
 
 
+//- Add lookup alias for runTime member selection.
+#define addAliasTemplateToMemberFunctionSelectionTable\
+(baseType,thisType,Targ,funcName,argNames,lookup,other,ver)                    \
+                                                                               \
+    /* Add thisType funcName to the table, find by lookup name */              \
+    baseType::addAlias##funcName##argNames##MemberFunctionToTable              \
+        <thisType<Targ>>                                                       \
+        add##thisType##Targ##funcName##argNames##MemberFunctionTo##baseType    \
+        ##lookup##_##other##_(#lookup,#other,ver)
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
 //- Add to hash-table of functions with typeName as the key.
 //  Use when baseType requires the Targ template argument as well
 #define addTemplatedToMemberFunctionSelectionTable\
@@ -106,6 +129,16 @@ Note
         add##thisType##Targ##funcName##argNames##MemberFunctionTo## \
         baseType##Targ##Table_##lookupName##_(#lookupName)
 
+//- Add lookup alias for runTime member selection.
+#define addAliasTemplatedToMemberFunctionSelectionTable\
+(baseType,thisType,Targ,funcName,argNames,lookup,other,ver)                    \
+                                                                               \
+    /* Add thisType funcName to the table, find by lookup name */              \
+    baseType<Targ>::addAlias##funcName##argNames##MemberFunctionToTable        \
+        <thisType<Targ>>                                                       \
+        add##thisType##Targ##funcName##argNames##MemberFunctionTo##baseType##  \
+        Targ##Table_##lookup##_##other##_(#lookup,#other,ver)
+
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/OpenFOAM/db/runTimeSelection/memberFunctions/memberFunctionSelectionTables.H b/src/OpenFOAM/db/runTimeSelection/memberFunctions/memberFunctionSelectionTables.H
index 206007a9b2a..bab205eff70 100644
--- a/src/OpenFOAM/db/runTimeSelection/memberFunctions/memberFunctionSelectionTables.H
+++ b/src/OpenFOAM/db/runTimeSelection/memberFunctions/memberFunctionSelectionTables.H
@@ -118,6 +118,22 @@ Note
         void operator=                                                         \
             (const addRemovable##funcName##argNames##MemberFunctionToTable&)   \
             = delete;                                                          \
+    };                                                                         \
+                                                                               \
+    /* Helper to add alias for funcName to table */                            \
+    template<class baseType##Type>                                             \
+    struct addAlias##funcName##argNames##MemberFunctionToTable                 \
+    {                                                                          \
+        explicit addAlias##funcName##argNames##MemberFunctionToTable           \
+        (                                                                      \
+            const ::Foam::word& k,                                             \
+            const ::Foam::word& alias,                                         \
+            const int ver                                                      \
+        )                                                                      \
+        {                                                                      \
+            funcName##argNames##MemberFunctionCompatTable()                    \
+                .set(alias, std::pair<::Foam::word,int>(k,ver));               \
+        }                                                                      \
     };
 
 
@@ -130,7 +146,7 @@ Note
 //- Define run-time selection table
 #define defineMemberFunctionSelectionTable(baseType,funcName,argNames)         \
                                                                                \
-    declareRunTimeSelectionTableBase(                                          \
+    defineRunTimeSelectionTableBase(                                           \
         baseType,baseType::funcName##argNames##MemberFunction,)
 
 
@@ -138,7 +154,7 @@ Note
 //  use when baseType doesn't need a template argument (eg, is a typedef)
 #define defineTemplateMemberFunctionSelectionTable(baseType,funcName,argNames) \
                                                                                \
-    declareRunTimeSelectionTableBase(                                          \
+    defineRunTimeSelectionTableBase(                                           \
         baseType,baseType::funcName##argNames##MemberFunction,template<>)
 
 
@@ -147,7 +163,7 @@ Note
 #define defineTemplatedMemberFunctionSelectionTable\
 (baseType,funcName,argNames,Targ)                                              \
                                                                                \
-    declareRunTimeSelectionTableBase(                                          \
+    defineRunTimeSelectionTableBase(                                           \
         baseType,baseType<Targ>::funcName##argNames##MemberFunction,template<>)
 
 
-- 
GitLab