From 7de49fd7f5c4e35392184f99d2485043cb8e274b Mon Sep 17 00:00:00 2001
From: Giovanni Bussi <giovanni.bussi@gmail.com>
Date: Tue, 31 Oct 2017 20:56:26 +0100
Subject: [PATCH] Improved syntax for ForwardDecl

Using ...Args it is easy to forward any argument to the constructor.

This allows avoiding to explicitly put "new" statements when initializing
a ForwardDecl. In addition, all ForwardDecl that should be constructed
without arguments can be omitted from the initialization list, which
significantly simplifies the code.
---
 developer-doc/plmdIntro.md          | 14 +++++++++-----
 src/core/ActionAtomistic.cpp        |  1 -
 src/core/Atoms.cpp                  |  1 -
 src/core/CLToolMain.cpp             |  3 +--
 src/core/ExchangePatterns.cpp       |  3 +--
 src/core/GREX.cpp                   |  2 --
 src/core/PlumedMain.cpp             | 11 ++---------
 src/core/SetupMolInfo.cpp           |  3 +--
 src/tools/ForwardDecl.h             | 12 ++++++++----
 src/vesselbase/ActionWithVessel.cpp |  1 -
 10 files changed, 22 insertions(+), 29 deletions(-)

diff --git a/developer-doc/plmdIntro.md b/developer-doc/plmdIntro.md
index c9a0a0434..c66bbd7e4 100644
--- a/developer-doc/plmdIntro.md
+++ b/developer-doc/plmdIntro.md
@@ -503,9 +503,13 @@ unique_ptr in advance, you should insert it with the following syntax
 
 Notice that also forward declarations discussed above are a bit simpler
 to implement using C++11 syntax. This can be done using a std::unique_ptr
-or, even better, using the class ForwardDecl, which is similar to
-a std::unique_ptr but only implements the necessary method in order to be
-less error prone.
+or, even better, using the class ForwardDecl, which is a small utility class that
+only implement two methods:
+- A constructor, which takes an arbitrary number of parameters and use them
+  to construct an internally stored `std::unique_ptr`.
+- A `operator *`, which returns a pointer to the object.
+
+An example usage is below:
 
 
 \verbatim
@@ -540,8 +544,8 @@ public:
 using namespace PLMD;
 
 B::B():
-  content1_fwd(*new A),
-  content2_fwd(*new A (argument))
+// constructors that need no argument can be omitted
+  content2_fwd(argument)
 {
 }
 
diff --git a/src/core/ActionAtomistic.cpp b/src/core/ActionAtomistic.cpp
index 35f6086d2..f65181c51 100644
--- a/src/core/ActionAtomistic.cpp
+++ b/src/core/ActionAtomistic.cpp
@@ -44,7 +44,6 @@ ActionAtomistic::~ActionAtomistic() {
 
 ActionAtomistic::ActionAtomistic(const ActionOptions&ao):
   Action(ao),
-  pbc_fwd(new(Pbc)),
   lockRequestAtoms(false),
   donotretrieve(false),
   donotforce(false),
diff --git a/src/core/Atoms.cpp b/src/core/Atoms.cpp
index 67b8e7ad6..7d723fe23 100644
--- a/src/core/Atoms.cpp
+++ b/src/core/Atoms.cpp
@@ -41,7 +41,6 @@ class PlumedMain;
 
 Atoms::Atoms(PlumedMain&plumed):
   natoms(0),
-  pbc_fwd(new Pbc),
   md_energy(0.0),
   energy(0.0),
   dataCanBeSet(false),
diff --git a/src/core/CLToolMain.cpp b/src/core/CLToolMain.cpp
index 0ac15965d..d422dda92 100644
--- a/src/core/CLToolMain.cpp
+++ b/src/core/CLToolMain.cpp
@@ -54,8 +54,7 @@ const std::unordered_map<std::string, int> & clToolMainWordMap() {
 CLToolMain::CLToolMain():
   argc(0),
   in(stdin),
-  out(stdout),
-  comm_fwd(new Communicator)
+  out(stdout)
 {
 }
 
diff --git a/src/core/ExchangePatterns.cpp b/src/core/ExchangePatterns.cpp
index 6da42b123..9f55d55bc 100644
--- a/src/core/ExchangePatterns.cpp
+++ b/src/core/ExchangePatterns.cpp
@@ -28,8 +28,7 @@ namespace PLMD {
 
 ExchangePatterns::ExchangePatterns():
   PatternFlag(NONE),
-  NumberOfReplicas(1),
-  random_fwd(new Random)
+  NumberOfReplicas(1)
 {}
 
 ExchangePatterns::~ExchangePatterns() {
diff --git a/src/core/GREX.cpp b/src/core/GREX.cpp
index 4476e8a9d..d71475847 100644
--- a/src/core/GREX.cpp
+++ b/src/core/GREX.cpp
@@ -44,8 +44,6 @@ const std::unordered_map<std::string, int> & GREXWordMap() {
 
 GREX::GREX(PlumedMain&p):
   initialized(false),
-  intracomm_fwd(new Communicator),
-  intercomm_fwd(new Communicator),
   plumedMain(p),
   atoms(p.getAtoms()),
   partner(-1), // = unset
diff --git a/src/core/PlumedMain.cpp b/src/core/PlumedMain.cpp
index 13d1cc00a..ae20f3390 100644
--- a/src/core/PlumedMain.cpp
+++ b/src/core/PlumedMain.cpp
@@ -63,22 +63,15 @@ const std::unordered_map<std::string, int> & plumedMainWordMap() {
 }
 
 PlumedMain::PlumedMain():
-  comm_fwd(new Communicator),
-  multi_sim_comm_fwd(new Communicator),
-  dlloader_fwd(new DLLoader),
-  stopwatch_fwd(new Stopwatch),
   initialized(false),
-  log_fwd(new Log),
-  citations_fwd(new Citations),
   step(0),
   active(false),
   mydatafetcher(DataFetchingObject::create(sizeof(double),*this)),
   endPlumed(false),
-  atoms_fwd(new Atoms(*this)),
-  actionSet_fwd(new ActionSet(*this)),
+  atoms_fwd(*this),
+  actionSet_fwd(*this),
   bias(0.0),
   work(0.0),
-  exchangePatterns_fwd(new(ExchangePatterns)),
   exchangeStep(false),
   restart(false),
   doCheckPoint(false),
diff --git a/src/core/SetupMolInfo.cpp b/src/core/SetupMolInfo.cpp
index 116d66653..878bfb19e 100644
--- a/src/core/SetupMolInfo.cpp
+++ b/src/core/SetupMolInfo.cpp
@@ -54,8 +54,7 @@ SetupMolInfo::~SetupMolInfo() {
 SetupMolInfo::SetupMolInfo( const ActionOptions&ao ):
   Action(ao),
   ActionSetup(ao),
-  ActionAtomistic(ao),
-  pdb_fwd(new(PDB))
+  ActionAtomistic(ao)
 {
   // Read what is contained in the pdb file
   parse("MOLTYPE",mytype);
diff --git a/src/tools/ForwardDecl.h b/src/tools/ForwardDecl.h
index 5e8fc253a..461f4fe07 100644
--- a/src/tools/ForwardDecl.h
+++ b/src/tools/ForwardDecl.h
@@ -23,6 +23,7 @@
 #define __PLUMED_tools_ForwardDecl_h
 
 #include <memory>
+#include <utility>
 
 namespace PLMD {
 
@@ -35,17 +36,20 @@ class ForwardDecl:
   std::unique_ptr<T>
 {
 public:
-// Construction is only possible from a pointer.
-  explicit ForwardDecl(T*);
+// Construction with arbitrary argument.
+  template<typename ...Args>
+  explicit ForwardDecl(Args &&...args);
 // Dereference operator is inherited from std::unique_ptr<T>
   using std::unique_ptr<T>::operator *;
 };
 
 template <class T>
-ForwardDecl<T>::ForwardDecl(T*x):
-  std::unique_ptr<T>(x)
+template<typename ...Args>
+ForwardDecl<T>::ForwardDecl(Args &&...args):
+  std::unique_ptr<T>(new T(std::forward<Args>(args)...))
 {}
 
+
 }
 
 #endif
diff --git a/src/vesselbase/ActionWithVessel.cpp b/src/vesselbase/ActionWithVessel.cpp
index 31f1644a5..aa7fec628 100644
--- a/src/vesselbase/ActionWithVessel.cpp
+++ b/src/vesselbase/ActionWithVessel.cpp
@@ -56,7 +56,6 @@ ActionWithVessel::ActionWithVessel(const ActionOptions&ao):
   noderiv(true),
   actionIsBridged(false),
   nactive_tasks(0),
-  stopwatch_fwd(new Stopwatch),
   dertime_can_be_off(false),
   dertime(true),
   contributorsAreUnlocked(false),
-- 
GitLab