From dc3b21555329fce63f71b1c567dc2e9c6ca3cfec Mon Sep 17 00:00:00 2001
From: Markus FRANK <Markus.Frank@cern.ch>
Date: Wed, 14 Apr 2021 20:28:27 +0200
Subject: [PATCH] Disable copy and move construction/assignment in Geant4 data

---
 DDG4/include/DDG4/DDG4Dict.h                 |  4 +-
 DDG4/include/DDG4/Geant4Data.h               | 20 ++++++++-
 DDG4/plugins/Geant4Processes.cpp             |  4 ++
 DDG4/plugins/Geant4SDActions.cpp             |  2 +-
 DDG4/plugins/Geant4TrackerWeightedSD.cpp     |  2 +-
 DDG4/src/Geant4Data.cpp                      |  8 ++--
 DDG4/src/Geant4Particle.cpp                  | 44 ++++++++++++--------
 DDG4/src/Geant4PhysicsList.cpp               | 26 ++++++------
 examples/DDG4_MySensDet/src/MyTrackerHit.cpp |  5 +--
 examples/DDG4_MySensDet/src/MyTrackerHit.h   |  2 +-
 10 files changed, 71 insertions(+), 46 deletions(-)

diff --git a/DDG4/include/DDG4/DDG4Dict.h b/DDG4/include/DDG4/DDG4Dict.h
index 00cbbccb7..e7ce4879c 100644
--- a/DDG4/include/DDG4/DDG4Dict.h
+++ b/DDG4/include/DDG4/DDG4Dict.h
@@ -145,8 +145,8 @@ namespace dd4hep {
     inline Geant4Tracker::Hit::Hit(int, int, double, double)   {}
     /// Default destructor
     inline Geant4Tracker::Hit::~Hit()  {    }
-    /// Assignment operator
-    inline Geant4Tracker::Hit& Geant4Tracker::Hit::operator=(const Hit&)   { return *this; }
+    /// Explicit assignment operation
+    inline void Geant4Tracker::Hit::copyFrom(const Hit&)   {   }
     /// Clear hit content
     inline Geant4Tracker::Hit& Geant4Tracker::Hit::clear()    { return *this; }
     /// Store Geant4 point and step information into tracker hit structure.
diff --git a/DDG4/include/DDG4/Geant4Data.h b/DDG4/include/DDG4/Geant4Data.h
index b79f7fe2d..c15d1bba5 100644
--- a/DDG4/include/DDG4/Geant4Data.h
+++ b/DDG4/include/DDG4/Geant4Data.h
@@ -238,12 +238,20 @@ namespace dd4hep {
       public:
         /// Default constructor
         Hit();
+        /// Move constructor
+        Hit(Hit&& c) = delete;
+        /// copy constructor
+        Hit(const Hit& c) = delete;
         /// Initializing constructor
         Hit(int track_id, int pdg_id, double deposit, double time_stamp);
         /// Default destructor
         virtual ~Hit();
-        /// Assignment operator
-        Hit& operator=(const Hit& c);
+        /// Move assignment operator
+        Hit& operator=(Hit&& c) = delete;
+        /// Copy assignment operator
+        Hit& operator=(const Hit& c) = delete;
+	/// Explicit assignment operation
+	void copyFrom(const Hit& c);
         /// Clear hit content
         Hit& clear();
         /// Store Geant4 point and step information into tracker hit structure.
@@ -280,10 +288,18 @@ namespace dd4hep {
       public:
         /// Default constructor (for ROOT)
         Hit();
+        /// Move constructor
+        Hit(Hit&& c) = delete;
+        /// copy constructor
+        Hit(const Hit& c) = delete;
         /// Standard constructor
         Hit(const Position& cell_pos);
         /// Default destructor
         virtual ~Hit();
+        /// Move assignment operator
+        Hit& operator=(Hit&& c) = delete;
+        /// Copy assignment operator
+        Hit& operator=(const Hit& c) = delete;
       };
     };
 
diff --git a/DDG4/plugins/Geant4Processes.cpp b/DDG4/plugins/Geant4Processes.cpp
index bc2503626..fbe5f3f22 100644
--- a/DDG4/plugins/Geant4Processes.cpp
+++ b/DDG4/plugins/Geant4Processes.cpp
@@ -38,6 +38,10 @@
 //
 // ======================================================================
 
+// Fast simulation
+#include "G4FastSimulationManagerProcess.hh"
+DECLARE_GEANT4_PROCESS(G4FastSimulationManagerProcess)
+
 // Photon Processes:
 #include "G4GammaConversion.hh"
 DECLARE_GEANT4_PROCESS(G4GammaConversion)
diff --git a/DDG4/plugins/Geant4SDActions.cpp b/DDG4/plugins/Geant4SDActions.cpp
index e544b1e9c..e005f4829 100644
--- a/DDG4/plugins/Geant4SDActions.cpp
+++ b/DDG4/plugins/Geant4SDActions.cpp
@@ -353,7 +353,7 @@ namespace dd4hep {
         sensitive->mark(step->GetTrack());
         mean_pos.SetXYZ(0,0,0);
         mean_time = 0;
-        post = pre;
+        post.copyFrom(pre);
         combined = 0;
         cell = 0;
       }
diff --git a/DDG4/plugins/Geant4TrackerWeightedSD.cpp b/DDG4/plugins/Geant4TrackerWeightedSD.cpp
index 0c2a831c2..b50c32218 100644
--- a/DDG4/plugins/Geant4TrackerWeightedSD.cpp
+++ b/DDG4/plugins/Geant4TrackerWeightedSD.cpp
@@ -130,7 +130,7 @@ namespace dd4hep {
         post.truth.deposit = 0.0;
         current = pre.truth.trackID;
         sensitive->mark(step->GetTrack());
-        post = pre;
+        post.copyFrom(pre);
         parent = step->GetTrack()->GetParentID();
         g4ID = step->GetTrack()->GetTrackID();
 
diff --git a/DDG4/src/Geant4Data.cpp b/DDG4/src/Geant4Data.cpp
index ac8a87381..794b6343e 100644
--- a/DDG4/src/Geant4Data.cpp
+++ b/DDG4/src/Geant4Data.cpp
@@ -92,7 +92,8 @@ Geant4HitData::Contribution Geant4HitData::extractContribution(const G4Step* ste
 
 /// Default constructor
 Geant4Tracker::Hit::Hit()
-: Geant4HitData(), position(), momentum(), length(0.0), truth(), energyDeposit(0.0) {
+: Geant4HitData(), position(), momentum(), length(0.0), truth(), energyDeposit(0.0)
+{
   InstanceCount::increment(this);
 }
 
@@ -107,15 +108,14 @@ Geant4Tracker::Hit::~Hit() {
   InstanceCount::decrement(this);
 }
 
-/// Assignment operator
-Geant4Tracker::Hit& Geant4Tracker::Hit::operator=(const Hit& c) {
+/// Explicit assignment operation
+void Geant4Tracker::Hit::copyFrom(const Hit& c) {
   if ( &c != this )  {
     position = c.position;
     momentum = c.momentum;
     length = c.length;
     truth = c.truth;
   }
-  return *this;
 }
 
 /// Clear hit content
diff --git a/DDG4/src/Geant4Particle.cpp b/DDG4/src/Geant4Particle.cpp
index 313fe9abc..1db6105c1 100644
--- a/DDG4/src/Geant4Particle.cpp
+++ b/DDG4/src/Geant4Particle.cpp
@@ -156,28 +156,36 @@ std::vector<G4ParticleDefinition*> Geant4ParticleHandle::g4DefinitionsRegEx(cons
   std::string exp = expression;   //'^'+expression+"$";
   G4ParticleTable* pt = G4ParticleTable::GetParticleTable();
   G4ParticleTable::G4PTblDicIterator* iter = pt->GetIterator();
-  char msgbuf[128];
-  regex_t reg;
-  int ret = ::regcomp(&reg, exp.c_str(), 0);
-  if (ret) {
-    throw std::runtime_error(format("Geant4ParticleHandle", "REGEX: Failed to compile particle name %s", exp.c_str()));
-  }
-  results.clear();
+
   iter->reset();
-  while ((*iter)()) {
-    G4ParticleDefinition* p = iter->value();
-    ret = ::regexec(&reg, p->GetParticleName().c_str(), 0, NULL, 0);
-    if (!ret)
+  if ( expression == "*" || expression == ".(*)" )   {
+    while ((*iter)()) {
+      G4ParticleDefinition* p = iter->value();
       results.emplace_back(p);
-    else if (ret == REG_NOMATCH)
-      continue;
-    else {
-      ::regerror(ret, &reg, msgbuf, sizeof(msgbuf));
-      ::regfree(&reg);
-      throw std::runtime_error(format("Geant4ParticleHandle", "REGEX: Failed to match particle name %s err=%s", exp.c_str(), msgbuf));
     }
   }
-  ::regfree(&reg);
+  else   {
+    regex_t reg;
+    int ret = ::regcomp(&reg, exp.c_str(), 0);
+    if (ret) {
+      throw std::runtime_error(format("Geant4ParticleHandle", "REGEX: Failed to compile particle name %s", exp.c_str()));
+    }
+    while ((*iter)()) {
+      G4ParticleDefinition* p = iter->value();
+      ret = ::regexec(&reg, p->GetParticleName().c_str(), 0, NULL, 0);
+      if (!ret)
+	results.emplace_back(p);
+      else if (ret == REG_NOMATCH)
+	continue;
+      else {
+	char msgbuf[128];
+	::regerror(ret, &reg, msgbuf, sizeof(msgbuf));
+	::regfree(&reg);
+	throw std::runtime_error(format("Geant4ParticleHandle", "REGEX: Failed to match particle name %s err=%s", exp.c_str(), msgbuf));
+      }
+    }
+    ::regfree(&reg);
+  }
   return results;
 }
 
diff --git a/DDG4/src/Geant4PhysicsList.cpp b/DDG4/src/Geant4PhysicsList.cpp
index 696a5411b..e87478af1 100644
--- a/DDG4/src/Geant4PhysicsList.cpp
+++ b/DDG4/src/Geant4PhysicsList.cpp
@@ -264,18 +264,17 @@ void Geant4PhysicsList::constructProcesses(G4VUserPhysicsList* physics_pointer)
     if ( defs.empty() )  {
       except("Particle:%s Cannot find the corresponding entry in the particle table.", part_name.c_str());
     }
-    for ( G4ParticleDefinition* particle : defs )   {
-      G4ProcessManager* mgr = particle->GetProcessManager();
-      for ( const Process& p : procs )  {
-        if ( G4VProcess* g4 = PluginService::Create<G4VProcess*>(p.name) )   {
+    for ( const Process& p : procs )  {
+      if ( G4VProcess* g4 = PluginService::Create<G4VProcess*>(p.name) )   {
+	for ( G4ParticleDefinition* particle : defs )   {
+	  G4ProcessManager* mgr = particle->GetProcessManager();
 	  mgr->AddDiscreteProcess(g4);
 	  info("Particle:%s -> [%s] added discrete process %s", 
 	       part_name.c_str(), particle->GetParticleName().c_str(), p.name.c_str());
-	  continue;
 	}
-	except("Particle:%s -> [%s] Cannot create discrete physics process %s", 
-	       part_name.c_str(), particle->GetParticleName().c_str(), p.name.c_str());
+	continue;
       }
+      except("Cannot create discrete physics process %s", p.name.c_str());
     }
   }
   for ( const auto& [part_name, procs] : m_processes )   {
@@ -283,19 +282,18 @@ void Geant4PhysicsList::constructProcesses(G4VUserPhysicsList* physics_pointer)
     if (defs.empty())  {
       except("Particle:%s Cannot find the corresponding entry in the particle table.", part_name.c_str());
     }
-    for ( G4ParticleDefinition* particle : defs )   {
-      G4ProcessManager* mgr = particle->GetProcessManager();
-      for ( const Process& p : procs )  {
-        if ( G4VProcess* g4 = PluginService::Create<G4VProcess*>(p.name) )   {
+    for ( const Process& p : procs )  {
+      if ( G4VProcess* g4 = PluginService::Create<G4VProcess*>(p.name) )   {
+	for ( G4ParticleDefinition* particle : defs )   {
+	  G4ProcessManager* mgr = particle->GetProcessManager();
 	  mgr->AddProcess(g4, p.ordAtRestDoIt, p.ordAlongSteptDoIt, p.ordPostStepDoIt);
 	  info("Particle:%s -> [%s] added process %s with flags (%d,%d,%d)", 
 	       part_name.c_str(), particle->GetParticleName().c_str(), p.name.c_str(),
 	       p.ordAtRestDoIt, p.ordAlongSteptDoIt, p.ordPostStepDoIt);
-	  continue;
 	}
-	except("Particle:%s -> [%s] Cannot create physics process %s", 
-	       part_name.c_str(), particle->GetParticleName().c_str(), p.name.c_str());
+	continue;
       }
+      except("Cannot create physics process %s", p.name.c_str());
     }
   }
 }
diff --git a/examples/DDG4_MySensDet/src/MyTrackerHit.cpp b/examples/DDG4_MySensDet/src/MyTrackerHit.cpp
index 532526e4d..dbd91edfa 100644
--- a/examples/DDG4_MySensDet/src/MyTrackerHit.cpp
+++ b/examples/DDG4_MySensDet/src/MyTrackerHit.cpp
@@ -18,12 +18,11 @@
 using namespace SomeExperiment;
 
 /// Assignment operator
-MyTrackerHit& MyTrackerHit::operator=(const MyTrackerHit& c)  {
+void MyTrackerHit::copyFrom(const MyTrackerHit& c)  {
   if ( &c != this )  {
-    this->dd4hep::sim::Geant4Tracker::Hit::operator=(c);
+    this->dd4hep::sim::Geant4Tracker::Hit::copyFrom(c);
     this->step_length = c.step_length;
     this->postPos = c.postPos;
     this->prePos = c.prePos;
   }
-  return *this;
 }
diff --git a/examples/DDG4_MySensDet/src/MyTrackerHit.h b/examples/DDG4_MySensDet/src/MyTrackerHit.h
index 759d2eb85..b7374b93d 100644
--- a/examples/DDG4_MySensDet/src/MyTrackerHit.h
+++ b/examples/DDG4_MySensDet/src/MyTrackerHit.h
@@ -52,7 +52,7 @@ namespace SomeExperiment {
     /// Default destructor
     virtual ~MyTrackerHit() = default;
     /// Assignment operator
-    MyTrackerHit& operator=(const MyTrackerHit& c);
+    void copyFrom(const MyTrackerHit& c);
   };
 
   /// Helper to dump data file
-- 
GitLab