From 78739f366ce9782b7927d8fda632ce912474e67b Mon Sep 17 00:00:00 2001
From: Martin Hierholzer <martin.hierholzer@desy.de>
Date: Tue, 26 Sep 2017 16:10:23 +0200
Subject: [PATCH] put the move constructor and move assignment-operator into
 the EntitiOwner base-class and inherit them

---
 include/ApplicationModule.h   | 15 +++++----------
 include/ControlSystemModule.h | 11 +++++++++++
 include/DeviceModule.h        | 11 +++++++++++
 include/EntityOwner.h         | 27 +++++++++++++++++++++++++++
 include/Module.h              |  6 ++++++
 include/ModuleGroup.h         | 34 ++++++----------------------------
 include/VariableGroup.h       | 16 +++++-----------
 src/ControlSystemModule.cc    |  2 +-
 src/DeviceModule.cc           |  2 +-
 9 files changed, 73 insertions(+), 51 deletions(-)

diff --git a/include/ApplicationModule.h b/include/ApplicationModule.h
index 19a914a3..5e0cf48f 100644
--- a/include/ApplicationModule.h
+++ b/include/ApplicationModule.h
@@ -39,7 +39,12 @@ namespace ChimeraTK {
        *  See this bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67054 */
       ApplicationModule() : Module(nullptr, "invalid", "invalid ApplicationModule") {}
 
+      /** Move operation with the move constructor */
+      ApplicationModule(ApplicationModule &&other) : Module(std::move(other)) {}
       
+      /** Inherit assignment */
+      using Module::operator=;
+
       /** Destructor */
       virtual ~ApplicationModule();
 
@@ -53,16 +58,6 @@ namespace ChimeraTK {
       VariableNetworkNode operator()(const std::string& variableName) const override;
 
       Module& operator[](const std::string& moduleName) const override;
-      
-      /** Move operation with the assignment operator */
-      ApplicationModule& operator=(ApplicationModule &&rhs) {
-        moduleThread = std::move(rhs.moduleThread);
-        _name = std::move(rhs._name);
-        _owner = std::move(rhs._owner);
-        accessorList = std::move(rhs.accessorList);
-        moduleList = std::move(rhs.moduleList);
-        return *this;
-      }
 
       ModuleType getModuleType() const override { return ModuleType::ApplicationModule; }
 
diff --git a/include/ControlSystemModule.h b/include/ControlSystemModule.h
index 417b7677..6ecc4911 100644
--- a/include/ControlSystemModule.h
+++ b/include/ControlSystemModule.h
@@ -25,6 +25,17 @@ namespace ChimeraTK {
        *  (separated by a slash). */
       ControlSystemModule(const std::string& variableNamePrefix="");
 
+      /** Move operation with the move constructor */
+      ControlSystemModule(ControlSystemModule &&other)
+      : Module(std::move(other)),
+        variableNamePrefix(std::move(other.variableNamePrefix)),
+        subModules(std::move(other.subModules)),
+        variables(std::move(other.variables))
+      {}
+      
+      /** Inherit assignment */
+      using Module::operator=;
+
       /** The function call operator returns a VariableNetworkNode which can be used in the Application::initialise()
        *  function to connect the control system variable with another variable. */
       VariableNetworkNode operator()(const std::string& variableName, const std::type_info &valueType,
diff --git a/include/DeviceModule.h b/include/DeviceModule.h
index e40eaa71..8fd7d907 100644
--- a/include/DeviceModule.h
+++ b/include/DeviceModule.h
@@ -28,6 +28,17 @@ namespace ChimeraTK {
       /** Default constructor: create dysfunctional device module */
       DeviceModule() {}
 
+      /** Move operation with the move constructor */
+      DeviceModule(DeviceModule &&other)
+      : Module(std::move(other)),
+        deviceAliasOrURI(std::move(other.deviceAliasOrURI)),
+        registerNamePrefix(std::move(other.registerNamePrefix)),
+        subModules(std::move(other.subModules))
+      {}
+      
+      /** Inherit assignment */
+      using Module::operator=;
+
       /** The subscript operator returns a VariableNetworkNode which can be used in the Application::initialise()
        *  function to connect the register with another variable. */
       VariableNetworkNode operator()(const std::string& registerName, UpdateMode mode,
diff --git a/include/EntityOwner.h b/include/EntityOwner.h
index adf3e4d4..148dfbb1 100644
--- a/include/EntityOwner.h
+++ b/include/EntityOwner.h
@@ -34,6 +34,33 @@ namespace ChimeraTK {
       
       /** Virtual destructor to make the type polymorphic */
       virtual ~EntityOwner();
+      
+      /** Move constructor */
+      EntityOwner(EntityOwner &&other)
+      : _name(std::move(other._name)),
+        _description(std::move(other._description)),
+        _owner(other._owner),
+        accessorList(std::move(other.accessorList)),
+        moduleList(std::move(other.moduleList)),
+        _eliminateHierarchy(other._eliminateHierarchy),
+        _tags(std::move(other._tags))
+      {}
+
+      /** Move operation with the assignment operator */
+      EntityOwner& operator=(EntityOwner &&other) {
+        _name = std::move(other._name);
+        _description = std::move(other._description);
+        _owner = std::move(other._owner);
+        accessorList = std::move(other.accessorList);
+        moduleList = std::move(other.moduleList);
+        _eliminateHierarchy = other._eliminateHierarchy;
+        _tags = std::move(other._tags);
+        return *this;
+      }
+      
+      /** Delete other assignment operators */
+      EntityOwner& operator=(EntityOwner &other) = delete;
+      EntityOwner& operator=(const EntityOwner &other) = delete;
 
       /** Get the name of the module instance */
       const std::string& getName() const { return _name; }
diff --git a/include/Module.h b/include/Module.h
index ecb02403..2286fb9b 100644
--- a/include/Module.h
+++ b/include/Module.h
@@ -35,6 +35,12 @@ namespace ChimeraTK {
 
       /** Destructor */
       virtual ~Module();
+      
+      /** Move operation with the move constructor */
+      Module(Module &&rhs) : EntityOwner(std::move(rhs)) {}
+      
+      /** Inherit assignment */
+      using EntityOwner::operator=;
 
       /** Prepare the execution of the module. This function is called before any module is started (including internal
        *  modules like FanOuts) and before the initial values of the variables are pushed into the queues. */
diff --git a/include/ModuleGroup.h b/include/ModuleGroup.h
index c37582bf..098618e7 100644
--- a/include/ModuleGroup.h
+++ b/include/ModuleGroup.h
@@ -37,36 +37,14 @@ namespace ChimeraTK {
        *  See this bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67054 */
       ModuleGroup() : Module(nullptr, "invalid", "invalid VariableGroup") {}
 
-      /** Destructor */
-      virtual ~ModuleGroup() {};
+      /** Move operation with the move constructor */
+      ModuleGroup(ModuleGroup &&other) : Module(std::move(other)) {}
       
-      /** Move operation with the move constructor
-          @todo should be in the base class!? */
-      ModuleGroup(ModuleGroup &&rhs) {
-        _name = std::move(rhs._name);
-        _owner = std::move(rhs._owner);
-        _description = std::move(rhs._description);
-        accessorList = std::move(rhs.accessorList);
-        moduleList = std::move(rhs.moduleList);
-        _eliminateHierarchy = rhs._eliminateHierarchy;
-        _tags = std::move(rhs._tags);
-      }
+      /** Inherit assignment */
+      using Module::operator=;
 
-      /** Move operation with the assignment operator
-          @todo should be in the base class!? */
-      ModuleGroup& operator=(ModuleGroup &&rhs) {
-        _name = std::move(rhs._name);
-        _owner = std::move(rhs._owner);
-        _description = std::move(rhs._description);
-        accessorList = std::move(rhs.accessorList);
-        moduleList = std::move(rhs.moduleList);
-        _eliminateHierarchy = rhs._eliminateHierarchy;
-        _tags = std::move(rhs._tags);
-        return *this;
-      }
-      
-      ModuleGroup& operator=(ModuleGroup &rhs) = delete;
-      ModuleGroup& operator=(const ModuleGroup &rhs) = delete;
+      /** Destructor */
+      virtual ~ModuleGroup() {};
 
       ModuleType getModuleType() const override { return ModuleType::ModuleGroup; }
 
diff --git a/include/VariableGroup.h b/include/VariableGroup.h
index 381df7dd..93d7f445 100644
--- a/include/VariableGroup.h
+++ b/include/VariableGroup.h
@@ -41,18 +41,12 @@ namespace ChimeraTK {
 
       /** Destructor */
       virtual ~VariableGroup() {};
+
+      /** Move operation with the move constructor */
+      VariableGroup(VariableGroup &&other) : Module(std::move(other)) {}
       
-      /** Move operation with the assignment operator
-          @todo should be in the base class!? */
-      VariableGroup& operator=(VariableGroup &&rhs) {
-        _name = std::move(rhs._name);
-        _owner = std::move(rhs._owner);
-        accessorList = std::move(rhs.accessorList);
-        moduleList = std::move(rhs.moduleList);
-        return *this;
-      }
-      
-      VariableGroup& operator=(VariableGroup &rhs) = delete;
+      /** Inherit assignment */
+      using Module::operator=;
 
       ModuleType getModuleType() const override { return ModuleType::VariableGroup; }
 
diff --git a/src/ControlSystemModule.cc b/src/ControlSystemModule.cc
index aa15d31f..804c2a27 100644
--- a/src/ControlSystemModule.cc
+++ b/src/ControlSystemModule.cc
@@ -29,7 +29,7 @@ namespace ChimeraTK {
 
   Module& ControlSystemModule::operator[](const std::string& moduleName) const {
     if(subModules.count(moduleName) == 0) {
-      subModules[moduleName] = {variableNamePrefix/moduleName};
+      subModules.emplace(std::pair<std::string, ControlSystemModule>(moduleName, ControlSystemModule(variableNamePrefix/moduleName)));
     }
     return subModules[moduleName];
   }
diff --git a/src/DeviceModule.cc b/src/DeviceModule.cc
index 5bc05cde..a0e77881 100644
--- a/src/DeviceModule.cc
+++ b/src/DeviceModule.cc
@@ -29,7 +29,7 @@ namespace ChimeraTK {
 
   Module& DeviceModule::operator[](const std::string& moduleName) const {
     if(subModules.count(moduleName) == 0) {
-      subModules[moduleName] = {deviceAliasOrURI, registerNamePrefix/moduleName};
+      subModules.emplace(std::pair<std::string, DeviceModule>(moduleName, DeviceModule(deviceAliasOrURI, registerNamePrefix/moduleName)));
     }
     return subModules[moduleName];
   }
-- 
GitLab