From 6a87dbcbcde3dd6ac0140b5a516f05feeb4722b7 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Mon, 10 Jan 2022 15:13:21 +0100
Subject: [PATCH] ENH: encapsulate wordRe regex with pointer

- reduces overall size and other overhead when wordRe represents
  a literal.
---
 src/OSspecific/MSwindows/regExp/regExp.H      |  4 +-
 src/OSspecific/MSwindows/regExp/regExpFwd.H   |  4 +-
 src/OSspecific/POSIX/regExp/regExp.H          |  4 +-
 src/OSspecific/POSIX/regExp/regExpFwd.H       |  4 +-
 src/OSspecific/POSIX/regExp/regExpPosix.H     |  4 +-
 .../primitives/strings/regex/regExpCxx.H      |  4 +-
 .../primitives/strings/wordRe/wordRe.C        |  8 ++-
 .../primitives/strings/wordRe/wordRe.H        | 14 ++--
 .../primitives/strings/wordRe/wordReI.H       | 67 +++++++++++++------
 9 files changed, 72 insertions(+), 41 deletions(-)

diff --git a/src/OSspecific/MSwindows/regExp/regExp.H b/src/OSspecific/MSwindows/regExp/regExp.H
index ba1284de1bf..05588995f55 100644
--- a/src/OSspecific/MSwindows/regExp/regExp.H
+++ b/src/OSspecific/MSwindows/regExp/regExp.H
@@ -31,8 +31,8 @@ Description
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef regExp_H
-#define regExp_H
+#ifndef Foam_regExp_H
+#define Foam_regExp_H
 
 #include "regExpCxx.H"
 #include "regExpFwd.H"
diff --git a/src/OSspecific/MSwindows/regExp/regExpFwd.H b/src/OSspecific/MSwindows/regExp/regExpFwd.H
index 48412a19416..a1968b5e99f 100644
--- a/src/OSspecific/MSwindows/regExp/regExpFwd.H
+++ b/src/OSspecific/MSwindows/regExp/regExpFwd.H
@@ -31,8 +31,8 @@ Description
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef regExpFwd_H
-#define regExpFwd_H
+#ifndef Foam_regExpFwd_H
+#define Foam_regExpFwd_H
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/OSspecific/POSIX/regExp/regExp.H b/src/OSspecific/POSIX/regExp/regExp.H
index 07e417c0ed4..4b53ce6d823 100644
--- a/src/OSspecific/POSIX/regExp/regExp.H
+++ b/src/OSspecific/POSIX/regExp/regExp.H
@@ -31,8 +31,8 @@ Description
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef regExp_H
-#define regExp_H
+#ifndef Foam_regExp_H
+#define Foam_regExp_H
 
 #include "regExpCxx.H"
 #include "regExpPosix.H"
diff --git a/src/OSspecific/POSIX/regExp/regExpFwd.H b/src/OSspecific/POSIX/regExp/regExpFwd.H
index 3b9586628fb..808e35663ae 100644
--- a/src/OSspecific/POSIX/regExp/regExpFwd.H
+++ b/src/OSspecific/POSIX/regExp/regExpFwd.H
@@ -31,8 +31,8 @@ Description
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef regExpFwd_H
-#define regExpFwd_H
+#ifndef Foam_regExpFwd_H
+#define Foam_regExpFwd_H
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/OSspecific/POSIX/regExp/regExpPosix.H b/src/OSspecific/POSIX/regExp/regExpPosix.H
index 585575c326d..8dd72cb6f01 100644
--- a/src/OSspecific/POSIX/regExp/regExpPosix.H
+++ b/src/OSspecific/POSIX/regExp/regExpPosix.H
@@ -64,8 +64,8 @@ SourceFiles
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef regExpPosix_H
-#define regExpPosix_H
+#ifndef Foam_regExpPosix_H
+#define Foam_regExpPosix_H
 
 #include "regExpCxx.H"
 #include <regex.h>
diff --git a/src/OpenFOAM/primitives/strings/regex/regExpCxx.H b/src/OpenFOAM/primitives/strings/regex/regExpCxx.H
index 92d1a353180..cb1672dab5b 100644
--- a/src/OpenFOAM/primitives/strings/regex/regExpCxx.H
+++ b/src/OpenFOAM/primitives/strings/regex/regExpCxx.H
@@ -65,8 +65,8 @@ SourceFiles
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef regExpCxx_H
-#define regExpCxx_H
+#ifndef Foam_regExpCxx_H
+#define Foam_regExpCxx_H
 
 #include <regex>
 #include <string>
diff --git a/src/OpenFOAM/primitives/strings/wordRe/wordRe.C b/src/OpenFOAM/primitives/strings/wordRe/wordRe.C
index 9f74c7ac23f..9de443e6597 100644
--- a/src/OpenFOAM/primitives/strings/wordRe/wordRe.C
+++ b/src/OpenFOAM/primitives/strings/wordRe/wordRe.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2018-2021 OpenCFD Ltd.
+    Copyright (C) 2018-2022 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -40,7 +40,8 @@ const Foam::wordRe Foam::wordRe::null;
 
 Foam::wordRe::wordRe(const keyType& str)
 :
-    word(str, false)  // No stripping
+    word(str, false),  // No stripping
+    regexPtr_(nullptr)
 {
     if (str.isPattern())
     {
@@ -50,6 +51,9 @@ Foam::wordRe::wordRe(const keyType& str)
 
 
 Foam::wordRe::wordRe(Istream& is)
+:
+    word(),
+    regexPtr_(nullptr)
 {
     is >> *this;
 }
diff --git a/src/OpenFOAM/primitives/strings/wordRe/wordRe.H b/src/OpenFOAM/primitives/strings/wordRe/wordRe.H
index b5b0536e340..4214aed38bf 100644
--- a/src/OpenFOAM/primitives/strings/wordRe/wordRe.H
+++ b/src/OpenFOAM/primitives/strings/wordRe/wordRe.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2017-2021 OpenCFD Ltd.
+    Copyright (C) 2017-2022 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -51,8 +51,8 @@ SourceFiles
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef wordRe_H
-#define wordRe_H
+#ifndef Foam_wordRe_H
+#define Foam_wordRe_H
 
 #include "word.H"
 #include "regExp.H"
@@ -85,7 +85,7 @@ class wordRe
     // Private Member Data
 
         //- The regular expression
-        regExp re_;
+        std::unique_ptr<Foam::regExp> regexPtr_;
 
 
 public:
@@ -164,10 +164,10 @@ public:
 
     // Access
 
-        //- The wordRe is treated as literal string, not as pattern.
+        //- The wordRe is a literal string, not a pattern.
         inline bool isLiteral() const noexcept;
 
-        //- The wordRe is treated as a pattern, not as literal string.
+        //- The wordRe is a pattern, not a literal string.
         inline bool isPattern() const noexcept;
 
 
@@ -181,7 +181,7 @@ public:
         //  \return false if the token was the incorrect type
         bool assign(const token& tok);
 
-        //- Compile as regular expression
+        //- Compile as regular expression (if possible)
         inline bool compile();
 
         //- Mark as literal string, remove any regular expression
diff --git a/src/OpenFOAM/primitives/strings/wordRe/wordReI.H b/src/OpenFOAM/primitives/strings/wordRe/wordReI.H
index 215f5da116c..16781316df8 100644
--- a/src/OpenFOAM/primitives/strings/wordRe/wordReI.H
+++ b/src/OpenFOAM/primitives/strings/wordRe/wordReI.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2017-2021 OpenCFD Ltd.
+    Copyright (C) 2017-2022 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -40,7 +40,7 @@ inline bool Foam::wordRe::valid(const char c)
 inline Foam::wordRe::wordRe()
 :
     word(),
-    re_()
+    regexPtr_(nullptr)
 {}
 
 
@@ -58,25 +58,28 @@ inline Foam::wordRe::wordRe(const wordRe& str)
 inline Foam::wordRe::wordRe(wordRe&& str)
 :
     word(std::move(static_cast<word&>(str))),
-    re_(std::move(str.re_))
+    regexPtr_(str.regexPtr_.release())
 {}
 
 
 inline Foam::wordRe::wordRe(const word& str)
 :
-    word(str)
+    word(str),
+    regexPtr_(nullptr)
 {}
 
 
 inline Foam::wordRe::wordRe(word&& str)
 :
-    word(std::move(str))
+    word(std::move(str)),
+    regexPtr_(nullptr)
 {}
 
 
 inline Foam::wordRe::wordRe(const std::string& str, const compOption opt)
 :
-    word(str, false)  // No stripping
+    word(str, false),  // No stripping
+    regexPtr_(nullptr)
 {
     if (opt != wordRe::LITERAL)
     {
@@ -87,7 +90,8 @@ inline Foam::wordRe::wordRe(const std::string& str, const compOption opt)
 
 inline Foam::wordRe::wordRe(const char* str, const compOption opt)
 :
-    word(str, false)  // No stripping
+    word(str, false),  // No stripping
+    regexPtr_(nullptr)
 {
     if (opt != wordRe::LITERAL)
     {
@@ -100,13 +104,13 @@ inline Foam::wordRe::wordRe(const char* str, const compOption opt)
 
 inline bool Foam::wordRe::isLiteral() const noexcept
 {
-    return !re_.exists();
+    return !bool(regexPtr_);
 }
 
 
 inline bool Foam::wordRe::isPattern() const noexcept
 {
-    return re_.exists();
+    return bool(regexPtr_);
 }
 
 
@@ -131,25 +135,47 @@ inline bool Foam::wordRe::compile(const compOption opt)
 
         if (comp)
         {
-            return re_.set(*this, (opt & wordRe::ICASE));
+            if (!regexPtr_)
+            {
+                regexPtr_.reset(new Foam::regExp());
+            }
+
+            if (!regexPtr_->set(*this, (opt & wordRe::ICASE)))
+            {
+                // Compilation failed
+                regexPtr_.reset(nullptr);
+            }
+
+            return bool(regexPtr_);
         }
     }
 
     // Fall-through behaviour - not a regex
-    re_.clear();
+    regexPtr_.reset(nullptr);
     return false;
 }
 
 
 inline bool Foam::wordRe::compile()
 {
-    return re_.set(*this);
+    if (!regexPtr_)
+    {
+        regexPtr_.reset(new Foam::regExp());
+    }
+
+    if (!regexPtr_->set(*this))
+    {
+        // Compilation failed
+        regexPtr_.reset(nullptr);
+    }
+
+    return bool(regexPtr_);
 }
 
 
 inline void Foam::wordRe::uncompile()
 {
-    re_.clear();
+    regexPtr_.reset(nullptr);
 }
 
 
@@ -160,22 +186,22 @@ inline void Foam::wordRe::uncompile(bool adjust)
     {
         string::stripInvalid<word>(*this);
     }
-    re_.clear();
+    regexPtr_.reset(nullptr);
 }
 
 
 inline void Foam::wordRe::clear()
 {
     word::clear();
-    re_.clear();
+    regexPtr_.reset(nullptr);
 }
 
 
 inline bool Foam::wordRe::match(const std::string& text, bool literal) const
 {
-    if (!literal && re_.exists())
+    if (!literal && regexPtr_)
     {
-        return re_.match(text);  // Match as regex
+        return regexPtr_->match(text);  // Match as regex
     }
 
     return !compare(text);  // Compare as literal
@@ -191,6 +217,7 @@ inline void Foam::wordRe::set(const std::string& str, const compOption opt)
 
 inline void Foam::wordRe::set(const char* str, const compOption opt)
 {
+    // No nullptr protection here
     assign(str);
     compile(opt);
 }
@@ -204,7 +231,7 @@ inline void Foam::wordRe::swap(wordRe& str)
     }
 
     word::swap(static_cast<word&>(str));
-    re_.swap(str.re_);
+    regexPtr_.swap(str.regexPtr_);
 }
 
 
@@ -230,7 +257,7 @@ inline void Foam::wordRe::operator=(const wordRe& str)
     }
     else
     {
-        re_.clear();
+        regexPtr_.reset(nullptr);
     }
 }
 
@@ -238,7 +265,7 @@ inline void Foam::wordRe::operator=(const wordRe& str)
 inline void Foam::wordRe::operator=(const word& str)
 {
     assign(str);
-    re_.clear();
+    regexPtr_.reset(nullptr);
 }
 
 
-- 
GitLab