Add a few C++ helper classes/macros.
authorTeemu Murtola <teemu.murtola@gmail.com>
Sun, 19 Feb 2012 12:11:17 +0000 (14:11 +0200)
committerTeemu Murtola <teemu.murtola@gmail.com>
Thu, 23 Feb 2012 17:30:33 +0000 (19:30 +0200)
- Macros to disable copying and/or assignment for a class. Although we
  don't want to use macros in general, I think for this purpose the
  macros actually make the code more readable (and also easier to
  write).
- Simple smart pointer class (that wraps boost::scoped_ptr) to help
  manage private implementation classes.  In addition to managing the
  memory and flagging common errors (like boost::scoped_ptr already
  does), it makes the compiler issue errors when the implementation
  class is modified in a const method.

Took them into use throughout the C++ code and fixed a few constness
issues.

Change-Id: Ifa9654e3a4c1979c15457ad07f7bf0462e13472f

43 files changed:
src/gromacs/analysisdata/abstractdata-impl.h
src/gromacs/analysisdata/abstractdata.cpp
src/gromacs/analysisdata/abstractdata.h
src/gromacs/analysisdata/analysisdata.cpp
src/gromacs/analysisdata/analysisdata.h
src/gromacs/analysisdata/datastorage.cpp
src/gromacs/analysisdata/datastorage.h
src/gromacs/analysisdata/modules/displacement.cpp
src/gromacs/analysisdata/modules/displacement.h
src/gromacs/analysisdata/modules/histogram.cpp
src/gromacs/analysisdata/modules/histogram.h
src/gromacs/analysisdata/modules/plot.cpp
src/gromacs/analysisdata/modules/plot.h
src/gromacs/analysisdata/tests/mock_module.cpp
src/gromacs/analysisdata/tests/mock_module.h
src/gromacs/fatalerror/messagestringcollector.cpp
src/gromacs/fatalerror/messagestringcollector.h
src/gromacs/options/abstractoptionstorage.h
src/gromacs/options/asciihelpwriter.cpp
src/gromacs/options/asciihelpwriter.h
src/gromacs/options/cmdlineparser.cpp
src/gromacs/options/cmdlineparser.h
src/gromacs/options/optioninfo.h
src/gromacs/options/options.cpp
src/gromacs/options/options.h
src/gromacs/options/optionsassigner.cpp
src/gromacs/options/optionsassigner.h
src/gromacs/options/optionsvisitor.h
src/gromacs/selection/selection.h
src/gromacs/selection/selectioncollection.cpp
src/gromacs/selection/selectioncollection.h
src/gromacs/trajectoryanalysis/analysismodule.cpp
src/gromacs/trajectoryanalysis/analysismodule.h
src/gromacs/trajectoryanalysis/analysissettings.cpp
src/gromacs/trajectoryanalysis/analysissettings.h
src/gromacs/trajectoryanalysis/cmdlinerunner.cpp
src/gromacs/trajectoryanalysis/cmdlinerunner.h
src/gromacs/trajectoryanalysis/runnercommon.cpp
src/gromacs/trajectoryanalysis/runnercommon.h
src/gromacs/utility/CMakeLists.txt
src/gromacs/utility/common.h [new file with mode: 0644]
src/testutils/refdata.cpp
src/testutils/refdata.h

index 9471424321a3bb46f6f483e114dfce9f37865568..5936af68dbedd8ab62cba42879c756d02af6a489 100644 (file)
@@ -84,16 +84,16 @@ class AbstractAnalysisData::Impl
 
         //! List of modules added to the data.
         ModuleList              _modules;
+        //! true if all modules support missing data.
+        bool                    _bAllowMissing;
         //! Whether notifyDataStart() has been called.
-        bool                    _bDataStart;
+        mutable bool            _bDataStart;
         //! Whether new data is being added.
-        bool                    _bInData;
+        mutable bool            _bInData;
         //! Whether data for a frame is being added.
-        bool                    _bInFrame;
-        //! true if all modules support missing data.
-        bool                    _bAllowMissing;
-        //! Header data for the current frame.
-        AnalysisDataFrameHeader _currHeader;
+        mutable bool            _bInFrame;
+        //! Index of the currently active frame.
+        mutable int             _currIndex;
         /*! \brief
          * Total number of frames in the data.
          *
index fc0fd9d1e66ce1dcc3e97de097b49dd2fad85fe9..5e69c27aa4c7d6a9dde3d4517ee87af8d6d951f6 100644 (file)
@@ -54,8 +54,8 @@ namespace gmx
  */
 
 AbstractAnalysisData::Impl::Impl()
-    : _bDataStart(false), _bInData(false), _bInFrame(false),
-      _bAllowMissing(true), _nframes(0)
+    : _bAllowMissing(true), _bDataStart(false), _bInData(false), _bInFrame(false),
+      _currIndex(-1), _nframes(0)
 {
 }
 
@@ -108,7 +108,6 @@ AbstractAnalysisData::AbstractAnalysisData()
 
 AbstractAnalysisData::~AbstractAnalysisData()
 {
-    delete _impl;
 }
 
 
@@ -270,7 +269,7 @@ AbstractAnalysisData::notifyFrameStart(const AnalysisDataFrameHeader &header) co
     GMX_ASSERT(header.index() == _impl->_nframes,
                "Out of order frames");
     _impl->_bInFrame = true;
-    _impl->_currHeader = header;
+    _impl->_currIndex = header.index();
 
     Impl::ModuleList::const_iterator i;
     for (i = _impl->_modules.begin(); i != _impl->_modules.end(); ++i)
@@ -286,7 +285,7 @@ AbstractAnalysisData::notifyPointsAdd(const AnalysisDataPointSetRef &points) con
     GMX_ASSERT(_impl->_bInData, "notifyDataStart() not called");
     GMX_ASSERT(_impl->_bInFrame, "notifyFrameStart() not called");
     GMX_ASSERT(points.lastColumn() < columnCount(), "Invalid columns");
-    GMX_ASSERT(points.frameIndex() == _impl->_currHeader.index(),
+    GMX_ASSERT(points.frameIndex() == _impl->_currIndex,
                "Points do not correspond to current frame");
     if (!_impl->_bAllowMissing && !points.allPresent())
     {
@@ -302,13 +301,14 @@ AbstractAnalysisData::notifyPointsAdd(const AnalysisDataPointSetRef &points) con
 
 
 void
-AbstractAnalysisData::notifyFrameFinish(const AnalysisDataFrameHeader &header) const
+AbstractAnalysisData::notifyFrameFinish(const AnalysisDataFrameHeader &header)
 {
     GMX_ASSERT(_impl->_bInData, "notifyDataStart() not called");
     GMX_ASSERT(_impl->_bInFrame, "notifyFrameStart() not called");
-    GMX_ASSERT(header.index() == _impl->_currHeader.index(),
+    GMX_ASSERT(header.index() == _impl->_currIndex,
                "Header does not correspond to current frame");
     _impl->_bInFrame = false;
+    _impl->_currIndex = -1;
 
     // Increment the counter before notifications to allow frame access from
     // modules.
index 0c793cb8e83b644dc19c189e429c96b6c65438e3..f2575512f473715d3c48a09f030cd1bd5123b682 100644 (file)
@@ -41,6 +41,8 @@
 
 #include "../legacyheaders/types/simple.h"
 
+#include "../utility/common.h"
+
 namespace gmx
 {
 
@@ -329,7 +331,7 @@ class AbstractAnalysisData
          * Should be called once for each call of notifyFrameStart(), after any
          * notifyPointsAdd() calls for the frame.
          */
-        void notifyFrameFinish(const AnalysisDataFrameHeader &header) const;
+        void notifyFrameFinish(const AnalysisDataFrameHeader &header);
         /*! \brief
          * Notifies attached modules of the end of data.
          *
@@ -341,7 +343,7 @@ class AbstractAnalysisData
     private:
         class Impl;
 
-        Impl                   *_impl;
+        PrivateImplPointer<Impl> _impl;
         int                     _ncol;
         bool                    _bMultiPoint;
 
@@ -349,10 +351,6 @@ class AbstractAnalysisData
          * Needed to provide access to notification methods.
          */
         friend class AnalysisDataStorage;
-
-        // Disallow copy and assign.
-        AbstractAnalysisData(const AbstractAnalysisData &);
-        void operator =(const AbstractAnalysisData &);
 };
 
 } // namespace gmx
index 4914a0c0eae4e3f6a5e5fb244dd906ce88ea6d96..c8d7b314accbab85b1ff697501bf905a4d950991 100644 (file)
@@ -82,7 +82,6 @@ AnalysisData::AnalysisData()
 
 AnalysisData::~AnalysisData()
 {
-    delete impl_;
 }
 
 
@@ -175,7 +174,6 @@ AnalysisDataHandle::AnalysisDataHandle(AnalysisData *data)
 
 AnalysisDataHandle::~AnalysisDataHandle()
 {
-    delete impl_;
 }
 
 
index 8522616c3d256096bdaa537b4aae21c5c88e307a..2dc2a9f0b93cf0b4d3c45fe0babf035c64cc3770 100644 (file)
@@ -100,11 +100,9 @@ class AnalysisData : public AbstractAnalysisData
 
         class Impl;
 
-        Impl                *impl_;
+        PrivateImplPointer<Impl> impl_;
 
         friend class AnalysisDataHandle;
-
-        // Copy and assign disallowed by base class.
 };
 
 
@@ -153,13 +151,9 @@ class AnalysisDataHandle
 
         class Impl;
 
-        Impl                   *impl_;
+        PrivateImplPointer<Impl> impl_;
 
         friend class AnalysisData;
-
-        // Disallow copy and assign.
-        AnalysisDataHandle(const AnalysisDataHandle &);
-        void operator =(const AnalysisDataHandle &);
 };
 
 } // namespace gmx
index 3c4360e8abfb4cbe1468d7deae9980949aa05f30..f3ae9163a7a8f03df2595870bfa797cf451427c4 100644 (file)
@@ -293,7 +293,6 @@ AnalysisDataStorage::AnalysisDataStorage()
 
 AnalysisDataStorage::~AnalysisDataStorage()
 {
-    delete impl_;
 }
 
 
index d056320fc4807046f51580e805da353b48caf9d0..d6e91e8cd8ebd73088dfbaea60b7da7ba76ed73c 100644 (file)
@@ -44,6 +44,7 @@
 #include "../legacyheaders/types/simple.h"
 
 #include "../fatalerror/gmxassert.h"
+#include "../utility/common.h"
 
 #include "dataframe.h"
 
@@ -201,9 +202,7 @@ class AnalysisDataStorageFrame
          */
         friend class AnalysisDataStorage;
 
-        // Disallow copy and assign.
-        AnalysisDataStorageFrame(const AnalysisDataStorageFrame &);
-        void operator =(const AnalysisDataStorageFrame &);
+        GMX_DISALLOW_COPY_AND_ASSIGN(AnalysisDataStorageFrame);
 };
 
 /*! \libinternal \brief
@@ -387,16 +386,12 @@ class AnalysisDataStorage
     private:
         class Impl;
 
-        Impl                   *impl_;
+        PrivateImplPointer<Impl> impl_;
 
         /*! \brief
          * Needed because the frame object needs to trigger notifications.
          */
         friend void AnalysisDataStorageFrame::finishPointSet();
-
-        // Disallow copy and assign.
-        AnalysisDataStorage(const AnalysisDataStorage &);
-        void operator =(const AnalysisDataStorage &);
 };
 
 } // namespace gmx
index de7da3f0cdfd7f65088d1aa11f3d00298c32594a..d269469bb87db49694ccf785f390d43df2b96ae1 100644 (file)
@@ -85,7 +85,6 @@ AnalysisDataDisplacementModule::AnalysisDataDisplacementModule()
 
 AnalysisDataDisplacementModule::~AnalysisDataDisplacementModule()
 {
-    delete _impl;
 }
 
 
index 9ad65eeb5ba4cd833cfb584547e8d8c01797f7ad..4bbc3e2ae4a25ffdb5c3627be39233ceaa8a0789 100644 (file)
@@ -93,7 +93,7 @@ class AnalysisDataDisplacementModule : public AbstractAnalysisData,
 
         class Impl;
 
-        Impl                   *_impl;
+        PrivateImplPointer<Impl> _impl;
 };
 
 } // namespace gmx
index cb7febac4b76eaa058424dff7674490a0f7c2aec..ce545dcfee32837fbfa11a70cf2e85024459417e 100644 (file)
@@ -480,7 +480,6 @@ AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule(
 
 AnalysisDataSimpleHistogramModule::~AnalysisDataSimpleHistogramModule()
 {
-    delete impl_;
 }
 
 
@@ -593,7 +592,6 @@ AnalysisDataWeightedHistogramModule::AnalysisDataWeightedHistogramModule(
 
 AnalysisDataWeightedHistogramModule::~AnalysisDataWeightedHistogramModule()
 {
-    delete impl_;
 }
 
 
index 0ebeb24a72b376e814faeb1e7813601ed22decf4..8d817ed35b6704b34bbbcb171b27c281203783e6 100644 (file)
@@ -361,7 +361,7 @@ class AnalysisDataSimpleHistogramModule : public AbstractAnalysisData,
         virtual AnalysisDataFrameRef tryGetDataFrameInternal(int index) const;
         virtual bool requestStorageInternal(int nframes);
 
-        internal::BasicHistogramImpl   *impl_;
+        PrivateImplPointer<internal::BasicHistogramImpl> impl_;
 
         // Copy and assign disallowed by base.
 };
@@ -412,7 +412,7 @@ class AnalysisDataWeightedHistogramModule : public AbstractAnalysisData,
         virtual AnalysisDataFrameRef tryGetDataFrameInternal(int index) const;
         virtual bool requestStorageInternal(int nframes);
 
-        internal::BasicHistogramImpl   *impl_;
+        PrivateImplPointer<internal::BasicHistogramImpl> impl_;
 
         // Copy and assign disallowed by base.
 };
index 4664b81cde583da91c05749b5cbbe08954ab3364..0f9325d44b827fedcd55be8c1370ca1667c17008 100644 (file)
@@ -146,7 +146,6 @@ AbstractPlotModule::AbstractPlotModule(const AnalysisDataPlotSettings &settings)
 
 AbstractPlotModule::~AbstractPlotModule()
 {
-    delete _impl;
 }
 
 
index fb88ba36a6c2a803d225a591b877b242e5a1480d..632e9a81d6abeaf623abe5a5b91ded961fd65830 100644 (file)
@@ -43,6 +43,7 @@
 
 #include "../datamodule.h"
 #include "../../options/timeunitmanager.h"
+#include "../../utility/common.h"
 
 namespace gmx
 {
@@ -219,11 +220,7 @@ class AbstractPlotModule : public AnalysisDataModuleInterface
     private:
         class Impl;
 
-        Impl                   *_impl;
-
-        // Disallow copy and assign.
-        AbstractPlotModule(const AbstractPlotModule &);
-        void operator =(const AbstractPlotModule &);
+        PrivateImplPointer<Impl> _impl;
 };
 
 
index d65ff02d6a2dab6b7313ae49d28f8ce22b9adbc5..cf76d7bed178da6f4b241f4f7b7a1b9f95de90a2 100644 (file)
@@ -337,7 +337,6 @@ MockAnalysisModule::MockAnalysisModule(int flags)
 
 MockAnalysisModule::~MockAnalysisModule()
 {
-    delete impl_;
 }
 
 
@@ -464,13 +463,13 @@ MockAnalysisModule::setupReferenceCheck(const TestReferenceChecker &checker,
     Expectation dataStart = EXPECT_CALL(*this, dataStarted(source));
     Expectation frameStart = EXPECT_CALL(*this, frameStarted(_))
         .After(dataStart)
-        .WillRepeatedly(Invoke(impl_, &Impl::startReferenceFrame));
+        .WillRepeatedly(Invoke(impl_.get(), &Impl::startReferenceFrame));
     Expectation pointsAdd = EXPECT_CALL(*this, pointsAdded(_))
         .After(dataStart)
-        .WillRepeatedly(Invoke(impl_, &Impl::checkReferencePoints));
+        .WillRepeatedly(Invoke(impl_.get(), &Impl::checkReferencePoints));
     Expectation frameFinish = EXPECT_CALL(*this, frameFinished(_))
         .After(dataStart)
-        .WillRepeatedly(Invoke(impl_, &Impl::finishReferenceFrame));
+        .WillRepeatedly(Invoke(impl_.get(), &Impl::finishReferenceFrame));
     EXPECT_CALL(*this, dataFinished())
         .After(frameStart, pointsAdd, frameFinish);
 }
index 7e6bcd7f56d20a42e081e31444fcb230c9979128..dc97aecc11df707347f8c9bee6a23fe5d038b010 100644 (file)
@@ -43,6 +43,7 @@
 #include <gmock/gmock.h>
 
 #include "gromacs/analysisdata/datamodule.h"
+#include "gromacs/utility/common.h"
 
 namespace gmx
 {
@@ -80,7 +81,7 @@ class MockAnalysisModule : public AnalysisDataModuleInterface
     private:
         class Impl;
 
-        Impl                   *impl_;
+        PrivateImplPointer<Impl> impl_;
 };
 
 } // namespace test
index 1016b81a4c25c8f4154c2196b444f026a8616710..3d9abd19b0dcaf84b882536dedb8d99df8edaa3c 100644 (file)
@@ -61,7 +61,6 @@ MessageStringCollector::MessageStringCollector()
 
 MessageStringCollector::~MessageStringCollector()
 {
-    delete impl_;
 }
 
 void MessageStringCollector::startContext(const char *name)
index e84cd11f2f8f5e3aa6f1076c8a6ecd42d74a60fa..6ddda7070b3f5bf0bf4c88e4d5d2f9836ca9d913 100644 (file)
@@ -41,6 +41,8 @@
 
 #include <string>
 
+#include "../utility/common.h"
+
 namespace gmx
 {
 
@@ -111,7 +113,7 @@ class MessageStringCollector
     private:
         class Impl;
 
-        Impl                   *impl_;
+        PrivateImplPointer<Impl> impl_;
 };
 
 /*! \libinternal \brief
@@ -154,7 +156,7 @@ class MessageStringContext
          * Adds a context for the given object.
          */
         MessageStringContext(MessageStringCollector *collector,
-                       const std::string &name)
+                             const std::string &name)
             : collector_(*collector)
         {
             collector_.startContext(name);
@@ -171,9 +173,7 @@ class MessageStringContext
         //! The wrapped object.
         MessageStringCollector &collector_;
 
-        // Disallow copy and assign.
-        MessageStringContext(const MessageStringContext &);
-        void operator =(const MessageStringContext &);
+        GMX_DISALLOW_COPY_AND_ASSIGN(MessageStringContext);
 };
 
 } // namespace gmx
index c8c2b6b4d16614222af174a040e6740816abaaf6..482c2c23f7fdb952b57da42849dd30b1e6db9736 100644 (file)
@@ -41,6 +41,8 @@
 
 #include <string>
 
+#include "../utility/common.h"
+
 #include "optionflags.h"
 
 namespace gmx
@@ -298,9 +300,7 @@ class AbstractOptionStorage
         //! Parent Options object.
         Options                *_options;
 
-        // Disallow copy and assign.
-        AbstractOptionStorage(const AbstractOptionStorage &);
-        void operator =(const AbstractOptionStorage &);
+        GMX_DISALLOW_COPY_AND_ASSIGN(AbstractOptionStorage);
 };
 
 } // namespace gmx
index 2ede5ac68640135d73d95104e82bda8e96659d36..d9d367e208168eaec9bd5416cee163feca4fda7b 100644 (file)
@@ -229,7 +229,6 @@ AsciiHelpWriter::AsciiHelpWriter(const Options &options)
 
 AsciiHelpWriter::~AsciiHelpWriter()
 {
-    delete _impl;
 }
 
 AsciiHelpWriter &AsciiHelpWriter::setShowHidden(bool bSet)
index ff190e52c1f88968f71e539e94088d6e870ffbeb..a400ef1ff12cacf68ed2ba2831326cf9ee0648db 100644 (file)
@@ -41,6 +41,8 @@
 
 #include <cstdio>
 
+#include "../utility/common.h"
+
 namespace gmx
 {
 
@@ -82,11 +84,7 @@ class AsciiHelpWriter
     private:
         class Impl;
 
-        Impl                   *_impl;
-
-        // Disallow copy and assign.
-        AsciiHelpWriter(const AsciiHelpWriter &);
-        void operator =(const AsciiHelpWriter &);
+        PrivateImplPointer<Impl> _impl;
 };
 
 } // namespace gmx
index 780175f1d3085fb4612d7c4deb2e490f004b2168..76acdcd8b0ab3b7ae92afd9452770ea0ab6c8590 100644 (file)
@@ -68,7 +68,6 @@ CommandLineParser::CommandLineParser(Options *options)
 
 CommandLineParser::~CommandLineParser()
 {
-    delete _impl;
 }
 
 void CommandLineParser::parse(int *argc, char *argv[])
index 4f480f284d0b94e9e0a33d6e82a6f7f0605ff15f..6198874f97d4e1bc9a8838bbf57630049e4968fc 100644 (file)
@@ -39,6 +39,8 @@
 #ifndef GMX_OPTIONS_CMDLINEPARSER_H
 #define GMX_OPTIONS_CMDLINEPARSER_H
 
+#include "../utility/common.h"
+
 namespace gmx
 {
 
@@ -83,11 +85,7 @@ class CommandLineParser
     private:
         class Impl;
 
-        Impl                   *_impl;
-
-        // Disallow copy and assign.
-        CommandLineParser(const CommandLineParser &);
-        void operator =(const CommandLineParser &);
+        PrivateImplPointer<Impl> _impl;
 };
 
 } // namespace gmx
index fa57c44f8ab4962a0b9b209503db0d6b66225be1..ecc2ec7fa7d15cdc10b5593b76b050242ad84c81 100644 (file)
@@ -43,6 +43,8 @@
 
 #include <string>
 
+#include "../utility/common.h"
+
 namespace gmx
 {
 
@@ -128,9 +130,7 @@ class OptionInfo
         //! The wrapped option.
         AbstractOptionStorage  &_option;
 
-        // Disallow copy and assign.
-        OptionInfo(const OptionInfo &);
-        void operator =(const OptionInfo &);
+        GMX_DISALLOW_COPY_AND_ASSIGN(OptionInfo);
 };
 
 } // namespace gmx
index 74f5bdecf6612d4542c68fadd6f7eafd1d971976..ba8b7ec5c4c9e657f304994dce7e3a19285edbcc 100644 (file)
@@ -144,7 +144,6 @@ Options::Options(const char *name, const char *title)
 
 Options::~Options()
 {
-    delete _impl;
 }
 
 const std::string &Options::name() const
index 299e365deda78c345e174eff96d9a5c3d91eb6b0..3d42d3a6815e78238721cb5aa22f78b06629bceb 100644 (file)
@@ -44,6 +44,8 @@
 
 #include <string>
 
+#include "../utility/common.h"
+
 namespace gmx
 {
 
@@ -172,9 +174,7 @@ class Options
     private:
         class Impl;
 
-        Impl                   *_impl;
-
-        friend class Impl;
+        PrivateImplPointer<Impl> _impl;
 
         //! Needed to be able to extend the interface of this object.
         friend class OptionsAssigner;
@@ -182,10 +182,6 @@ class Options
         friend class OptionsIterator;
         //! Needed to be able to extend the interface of this object.
         friend class OptionsModifyingIterator;
-
-        // Disallow copy and assign.
-        Options(const Options &);
-        void operator =(const Options &);
 };
 
 } // namespace gmx
index af0991bedc1606b12599786e796a2ea44ddf4c63..95f8ec9a2c56dbaecdd3e1f70d07d54c487583e8 100644 (file)
@@ -158,7 +158,6 @@ OptionsAssigner::OptionsAssigner(Options *options)
 
 OptionsAssigner::~OptionsAssigner()
 {
-    delete _impl;
 }
 
 void OptionsAssigner::setAcceptBooleanNoPrefix(bool enabled)
index de6c557305410c90eee50e372f07a5881397407b..e33981d702d8a0cca35fe003b8d37c6323988683 100644 (file)
@@ -43,6 +43,8 @@
 
 #include <string>
 
+#include "../utility/common.h"
+
 namespace gmx
 {
 
@@ -200,11 +202,7 @@ class OptionsAssigner
     private:
         class Impl;
 
-        Impl                   *_impl;
-
-        // Disallow copy and assign.
-        OptionsAssigner(const OptionsAssigner &);
-        void operator =(const OptionsAssigner &);
+        PrivateImplPointer<Impl> _impl;
 };
 
 } // namespace gmx
index 280120c4c9ec21559a9a53d1f94f110f52ab63fe..306b0ab44d1824c889a2b9977ec843f0c5074daa 100644 (file)
@@ -43,6 +43,8 @@
 
 #include <string>
 
+#include "../utility/common.h"
+
 #include "optioninfo.h"
 
 namespace gmx
@@ -157,9 +159,7 @@ class OptionsIterator
         //! The wrapped Options object.
         const Options          &_options;
 
-        // Disallow copy and assign.
-        OptionsIterator(const OptionsIterator &);
-        void operator =(const OptionsIterator &);
+        GMX_DISALLOW_COPY_AND_ASSIGN(OptionsIterator);
 };
 
 /*! \libinternal \brief
@@ -251,9 +251,7 @@ class OptionsModifyingIterator
         //! The wrapped Options object.
         Options                &_options;
 
-        // Disallow copy and assign.
-        OptionsModifyingIterator(const OptionsModifyingIterator &);
-        void operator =(const OptionsModifyingIterator &);
+        GMX_DISALLOW_COPY_AND_ASSIGN(OptionsModifyingIterator);
 };
 
 } // namespace gmx
index 768ededc3ad6607edbef8dee81d1bcba7c1efa65..267f66807167138946d9785d4e9b59cff32715f8 100644 (file)
@@ -46,6 +46,7 @@
 
 #include "../fatalerror/gmxassert.h"
 #include "../utility/arrayref.h"
+#include "../utility/common.h"
 
 #include "position.h"
 #include "indexutil.h"
@@ -259,9 +260,7 @@ class Selection
          */
         friend class SelectionPosition;
 
-        // Disallow copy and assign.
-        Selection(const Selection &);
-        void operator =(const Selection &);
+        GMX_DISALLOW_COPY_AND_ASSIGN(Selection);
 };
 
 /*! \brief
index e9d8a582c3eccb0b741d54bf7142a302a1604ac5..e23b798d62f2738cd23508eac3d0afd7b7c9f35a 100644 (file)
@@ -262,7 +262,6 @@ SelectionCollection::SelectionCollection(gmx_ana_poscalc_coll_t *pcc)
 
 SelectionCollection::~SelectionCollection()
 {
-    delete _impl;
 }
 
 
@@ -637,19 +636,17 @@ SelectionCollection::printTree(FILE *fp, bool bValues) const
 void
 SelectionCollection::printXvgrInfo(FILE *out, output_env_t oenv) const
 {
-    int  i;
-
     if (output_env_get_xvg_format(oenv) != exvgNONE)
     {
-        gmx_ana_selcollection_t *sc = &_impl->_sc;
+        const gmx_ana_selcollection_t &sc = _impl->_sc;
         std::fprintf(out, "# Selections:\n");
-        for (i = 0; i < sc->nvars; ++i)
+        for (int i = 0; i < sc.nvars; ++i)
         {
-            std::fprintf(out, "#   %s\n", sc->varstrs[i]);
+            std::fprintf(out, "#   %s\n", sc.varstrs[i]);
         }
-        for (i = 0; i < (int)sc->sel.size(); ++i)
+        for (size_t i = 0; i < sc.sel.size(); ++i)
         {
-            std::fprintf(out, "#   %s\n", sc->sel[i]->selectionText());
+            std::fprintf(out, "#   %s\n", sc.sel[i]->selectionText());
         }
         std::fprintf(out, "#\n");
     }
index 618df47d4ccb13992956320b34db6f240052b8ea..d1f0d352e73b2c7692f95629977a2900de81fa6c 100644 (file)
@@ -42,7 +42,9 @@
 #include <string>
 #include <vector>
 
-#include <typedefs.h>
+#include "../legacyheaders/typedefs.h"
+
+#include "../utility/common.h"
 
 struct gmx_ana_indexgrps_t;
 struct gmx_ana_poscalc_coll_t;
@@ -304,7 +306,7 @@ class SelectionCollection
     private:
         class Impl;
 
-        Impl                   *_impl;
+        PrivateImplPointer<Impl> _impl;
 
         /*! \brief
          * Needed for the compiler to freely modify the collection.
@@ -318,10 +320,6 @@ class SelectionCollection
          * Needed for handling delayed selection parsing requests.
          */
         friend class SelectionOptionStorage;
-
-        // Disallow copy and assign.
-        SelectionCollection(const SelectionCollection &);
-        void operator =(const SelectionCollection &);
 };
 
 } // namespace gmx
index 63292c8f92ee2dbed6a163b3a19152e939410c02..a21aa6fd65ffe185969ea171bbd1091a7f512587 100644 (file)
@@ -95,7 +95,6 @@ TrajectoryAnalysisModuleData::TrajectoryAnalysisModuleData(
 
 TrajectoryAnalysisModuleData::~TrajectoryAnalysisModuleData()
 {
-    delete _impl;
 }
 
 
@@ -166,7 +165,6 @@ TrajectoryAnalysisModule::TrajectoryAnalysisModule()
 
 TrajectoryAnalysisModule::~TrajectoryAnalysisModule()
 {
-    delete _impl;
 }
 
 
@@ -211,7 +209,11 @@ AbstractAnalysisData *TrajectoryAnalysisModule::datasetFromIndex(int index) cons
     {
         return NULL;
     }
-    return _impl->_datasets[_impl->_datasetNames[index]];
+    Impl::DatasetContainer::const_iterator item
+        = _impl->_datasets.find(_impl->_datasetNames[index]);
+    GMX_RELEASE_ASSERT(item != _impl->_datasets.end(),
+                       "Inconsistent data set names");
+    return item->second;
 }
 
 
@@ -229,7 +231,8 @@ AbstractAnalysisData *TrajectoryAnalysisModule::datasetFromName(const char *name
 void TrajectoryAnalysisModule::registerBasicDataset(AbstractAnalysisData *data,
                                                     const char *name)
 {
-    // TODO: Check for duplicates
+    GMX_RELEASE_ASSERT(datasetFromName(name) == NULL,
+                       "Duplicate data set name registered");
     _impl->_datasets[name] = data;
     _impl->_datasetNames.push_back(name);
 }
index 1a25e50dbb01dfa323d6cfb0b992e52995eff668..73382d35a52c5a8643ca38ab5b8d73ce8139305d 100644 (file)
@@ -45,6 +45,8 @@
 
 #include "../legacyheaders/typedefs.h"
 
+#include "../utility/common.h"
+
 namespace gmx
 {
 
@@ -129,11 +131,7 @@ class TrajectoryAnalysisModuleData
     private:
         class Impl;
 
-        Impl                   *_impl;
-
-        // Disallow copy and assign.
-        TrajectoryAnalysisModuleData(const TrajectoryAnalysisModuleData &);
-        void operator =(const TrajectoryAnalysisModuleData &);
+        PrivateImplPointer<Impl> _impl;
 };
 
 
@@ -344,16 +342,12 @@ class TrajectoryAnalysisModule
     private:
         class Impl;
 
-        Impl                   *_impl;
+        PrivateImplPointer<Impl> _impl;
 
         /*! \brief
          * Needed to access the registered analysis data sets.
          */
         friend class TrajectoryAnalysisModuleData;
-
-        // Disallow copy and assign.
-        TrajectoryAnalysisModule(const TrajectoryAnalysisModule &);
-        void operator =(const TrajectoryAnalysisModule &);
 };
 
 } // namespace gmx
index 59f37345dcd98a10effe0532dbb2a0736f9567df..cd7d71bc939a592e4a3e9d5d77668423216d5364 100644 (file)
@@ -65,7 +65,6 @@ TrajectoryAnalysisSettings::TrajectoryAnalysisSettings()
 
 TrajectoryAnalysisSettings::~TrajectoryAnalysisSettings()
 {
-    delete _impl;
 }
 
 
index 47a322fc000ff7991ee3de85497c6f8fc1c88f74..1840caaed97f65d49207d8e82ee2cc0474b6d79e 100644 (file)
@@ -42,6 +42,7 @@
 #include "../legacyheaders/typedefs.h"
 
 #include "../options/timeunitmanager.h"
+#include "../utility/common.h"
 
 namespace gmx
 {
@@ -216,11 +217,7 @@ class TrajectoryAnalysisSettings
     private:
         class Impl;
 
-        Impl                   *_impl;
-
-        // Disallow copy and assign.
-        TrajectoryAnalysisSettings(const TrajectoryAnalysisSettings &);
-        void operator =(const TrajectoryAnalysisSettings &);
+        PrivateImplPointer<Impl> _impl;
 
         friend class TrajectoryAnalysisRunnerCommon;
 };
@@ -272,9 +269,7 @@ class TopologyInformation
         //! The ePBC field loaded from the topology file.
         int                  _ePBC;
 
-        // Disallow copy and assign.
-        TopologyInformation(const TopologyInformation &);
-        void operator =(const TopologyInformation &);
+        GMX_DISALLOW_COPY_AND_ASSIGN(TopologyInformation);
 
         friend class TrajectoryAnalysisRunnerCommon;
 };
index 54a0a0b2971e2945e244d7ab30a0ee3728b35e44..e11d2d1b16f4727e99be7bf6ec8a01c48ad48af8 100644 (file)
@@ -189,7 +189,6 @@ TrajectoryAnalysisCommandLineRunner::TrajectoryAnalysisCommandLineRunner(
 
 TrajectoryAnalysisCommandLineRunner::~TrajectoryAnalysisCommandLineRunner()
 {
-    delete _impl;
 }
 
 
index a43554b82c7d69c5a6601ec0f59ce4bf65f8c140..a4cce2ecec2c3591cadc38955f9613db8450ce1e 100644 (file)
@@ -39,6 +39,8 @@
 #ifndef GMX_TRAJECTORYANALYSIS_CMDLINERUNNER_H
 #define GMX_TRAJECTORYANALYSIS_CMDLINERUNNER_H
 
+#include "../utility/common.h"
+
 namespace gmx
 {
 
@@ -84,11 +86,7 @@ class TrajectoryAnalysisCommandLineRunner
     private:
         class Impl;
 
-        Impl                *_impl;
-
-        // Disallow copy and assign.
-        TrajectoryAnalysisCommandLineRunner(const TrajectoryAnalysisCommandLineRunner &);
-        void operator =(const TrajectoryAnalysisCommandLineRunner &);
+        PrivateImplPointer<Impl> _impl;
 };
 
 } // namespace gmx
index df609b44597086f10aff8dbf624e5918986c12ab..94f29a77a1b27d3a9d37277447f5eacd218dabd5 100644 (file)
@@ -158,7 +158,6 @@ TrajectoryAnalysisRunnerCommon::TrajectoryAnalysisRunnerCommon(
 
 TrajectoryAnalysisRunnerCommon::~TrajectoryAnalysisRunnerCommon()
 {
-    delete _impl;
 }
 
 
index 3a4575f02a2305a881d996ea05242fbf742d68ce..d7cdc1abea9a12541247f807631340fa95b606a0 100644 (file)
@@ -38,7 +38,7 @@
 #ifndef GMX_TRAJECTORYANALYSIS_RUNNERCOMMON_H
 #define GMX_TRAJECTORYANALYSIS_RUNNERCOMMON_H
 
-#include <typedefs.h>
+#include "../utility/common.h"
 
 namespace gmx
 {
@@ -96,11 +96,7 @@ class TrajectoryAnalysisRunnerCommon
     private:
         class Impl;
 
-        Impl                *_impl;
-
-        // Disallow copy and assign.
-        TrajectoryAnalysisRunnerCommon(const TrajectoryAnalysisRunnerCommon &);
-        void operator =(const TrajectoryAnalysisRunnerCommon &);
+        PrivateImplPointer<Impl> _impl;
 };
 
 } // namespace gmx
index 05722d7ed12db6bcdec2cbfba3c3d0354d533ca2..92fe961d2e66e42214eaddffc6bdefb65d517d1b 100644 (file)
@@ -2,7 +2,7 @@ file(GLOB UTILITY_SOURCES *.cpp)
 set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${UTILITY_SOURCES} PARENT_SCOPE)
 
 set(UTILITY_PUBLIC_HEADERS
-    arrayref.h flags.h format.h)
+    arrayref.h common.h flags.h format.h)
 install(FILES ${UTILITY_PUBLIC_HEADERS}
         DESTINATION ${INCL_INSTALL_DIR}/gromacs/utility
         COMPONENT development)
diff --git a/src/gromacs/utility/common.h b/src/gromacs/utility/common.h
new file mode 100644 (file)
index 0000000..2e8cd87
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ *
+ *                This source code is part of
+ *
+ *                 G   R   O   M   A   C   S
+ *
+ *          GROningen MAchine for Chemical Simulations
+ *
+ * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2009, The GROMACS development team,
+ * check out http://www.gromacs.org for more information.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * If you want to redistribute modifications, please consider that
+ * scientific software is very special. Version control is crucial -
+ * bugs must be traceable. We will be happy to consider code for
+ * inclusion in the official distribution, but derived work must not
+ * be called official GROMACS. Details are found in the README & COPYING
+ * files - if they are missing, get the official version at www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the papers on the package - you can find them in the top README file.
+ *
+ * For more info, check our website at http://www.gromacs.org
+ */
+/*! \file
+ * \brief
+ * Declares common utility classes and macros.
+ *
+ * This header contains helpers used to implement classes in the library.
+ * It is installed, because the helpers are used in installed headers, but
+ * typically users of the library should not need to be aware of these helpers.
+ *
+ * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+#ifndef GMX_UTILITY_COMMON_H
+#define GMX_UTILITY_COMMON_H
+
+#include <boost/scoped_ptr.hpp>
+
+/*! \libinternal \brief
+ * Macro to declare a class non-copyable and non-assignable.
+ *
+ * For consistency, should appear last in the class declaration.
+ *
+ * \inlibraryapi
+ */
+#define GMX_DISALLOW_COPY_AND_ASSIGN(ClassName) \
+    private: \
+        ClassName(const ClassName &); \
+        ClassName &operator =(const ClassName &)
+/*! \libinternal \brief
+ * Macro to declare a class non-assignable.
+ *
+ * For consistency, should appear last in the class declaration.
+ *
+ * \inlibraryapi
+ */
+#define GMX_DISALLOW_ASSIGN(ClassName) \
+    private: \
+        ClassName &operator =(const ClassName &)
+
+namespace gmx
+{
+
+/*! \libinternal \brief
+ * Helper class to manage a pointer to a private implementation class.
+ *
+ * This helper provides the following benefits (the first two could also be
+ * achieved with boost::scoped_ptr):
+ *  - Automatic memory management: the implementation pointer is freed in
+ *    the destructor automatically.  If the destructor is not declared or is
+ *    defined inline in the header file, a compilation error occurs instead
+ *    of a memory leak or undefined behavior.
+ *  - Copy and/or assignment is automatically disallowed if explicit copy
+ *    constructor and/or assignment operator is not provided.
+ *  - Compiler helps to manage const-correctness: in const methods, it is not
+ *    possible to change the implementation class.
+ *
+ * Intended use:
+ * \code
+// In exampleclass.h
+class ExampleClass
+{
+    public:
+        ExampleClass();
+        ~ExampleClass(); // Must not be defined inline
+
+        // <...>
+
+    private:
+        class Impl;
+
+        PrivateImplPointer<Impl> impl_;
+};
+
+// In exampleclass.cpp
+
+// <definition of ExampleClass::Impl>
+
+ExampleClass::ExampleClass()
+    : impl_(new Impl)
+{
+}
+
+ExampleClass::~ExampleClass()
+{
+}
+ * \endcode
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+template <class Impl>
+class PrivateImplPointer
+{
+    public:
+        //! Initialize with the given implementation class.
+        explicit PrivateImplPointer(Impl *ptr) : ptr_(ptr) {}
+        ~PrivateImplPointer() {}
+
+        void reset(Impl *ptr) { ptr_.reset(ptr); }
+        Impl *get() { return ptr_.get(); }
+        Impl *operator->() { return ptr_.get(); }
+        Impl &operator*() { return *ptr_; }
+        const Impl *get() const { return ptr_.get(); }
+        const Impl *operator->() const { return ptr_.get(); }
+        const Impl &operator*() const { return *ptr_; }
+
+    private:
+        boost::scoped_ptr<Impl> ptr_;
+
+        // Copy and assign disabled by the scoped_ptr member.
+};
+
+} // namespace gmx
+
+#endif
index 608ad72db974441f2c9e2cb5799ab57e609bb745..c837bbee5e74a9856dad6b95ef7683057479c0f9 100644 (file)
@@ -355,7 +355,6 @@ TestReferenceData::TestReferenceData(ReferenceDataMode mode)
 
 TestReferenceData::~TestReferenceData()
 {
-    delete _impl;
 }
 
 
@@ -402,16 +401,13 @@ TestReferenceChecker::TestReferenceChecker(const TestReferenceChecker &other)
 TestReferenceChecker &
 TestReferenceChecker::operator =(const TestReferenceChecker &other)
 {
-    Impl *newImpl = new Impl(*other._impl);
-    std::swap(_impl, newImpl);
-    delete newImpl;
+    _impl.reset(new Impl(*other._impl));
     return *this;
 }
 
 
 TestReferenceChecker::~TestReferenceChecker()
 {
-    delete _impl;
 }
 
 
index 188315c9855efeca609d3d99cc56fd559f7ac966..2fe7efab9aa87544feef4abc08ae3685f390fa0f 100644 (file)
@@ -42,6 +42,8 @@
 #include <iterator>
 #include <string>
 
+#include "gromacs/utility/common.h"
+
 namespace gmx
 {
 namespace test
@@ -211,11 +213,7 @@ class TestReferenceData
     private:
         class Impl;
 
-        Impl                   *_impl;
-
-        // Disallow copy and assign.
-        TestReferenceData(const TestReferenceData &);
-        void operator =(const TestReferenceData &);
+        PrivateImplPointer<Impl> _impl;
 };
 
 /*! \libinternal \brief
@@ -465,7 +463,7 @@ class TestReferenceChecker
          */
         explicit TestReferenceChecker(Impl *impl);
 
-        Impl                   *_impl;
+        PrivateImplPointer<Impl> _impl;
 
         /*! \brief
          * Needed to expose the constructor only to TestReferenceData.