//! 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.
*
*/
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)
{
}
AbstractAnalysisData::~AbstractAnalysisData()
{
- delete _impl;
}
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)
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())
{
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.
#include "../legacyheaders/types/simple.h"
+#include "../utility/common.h"
+
namespace gmx
{
* 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.
*
private:
class Impl;
- Impl *_impl;
+ PrivateImplPointer<Impl> _impl;
int _ncol;
bool _bMultiPoint;
* Needed to provide access to notification methods.
*/
friend class AnalysisDataStorage;
-
- // Disallow copy and assign.
- AbstractAnalysisData(const AbstractAnalysisData &);
- void operator =(const AbstractAnalysisData &);
};
} // namespace gmx
AnalysisData::~AnalysisData()
{
- delete impl_;
}
AnalysisDataHandle::~AnalysisDataHandle()
{
- delete impl_;
}
class Impl;
- Impl *impl_;
+ PrivateImplPointer<Impl> impl_;
friend class AnalysisDataHandle;
-
- // Copy and assign disallowed by base class.
};
class Impl;
- Impl *impl_;
+ PrivateImplPointer<Impl> impl_;
friend class AnalysisData;
-
- // Disallow copy and assign.
- AnalysisDataHandle(const AnalysisDataHandle &);
- void operator =(const AnalysisDataHandle &);
};
} // namespace gmx
AnalysisDataStorage::~AnalysisDataStorage()
{
- delete impl_;
}
#include "../legacyheaders/types/simple.h"
#include "../fatalerror/gmxassert.h"
+#include "../utility/common.h"
#include "dataframe.h"
*/
friend class AnalysisDataStorage;
- // Disallow copy and assign.
- AnalysisDataStorageFrame(const AnalysisDataStorageFrame &);
- void operator =(const AnalysisDataStorageFrame &);
+ GMX_DISALLOW_COPY_AND_ASSIGN(AnalysisDataStorageFrame);
};
/*! \libinternal \brief
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
AnalysisDataDisplacementModule::~AnalysisDataDisplacementModule()
{
- delete _impl;
}
class Impl;
- Impl *_impl;
+ PrivateImplPointer<Impl> _impl;
};
} // namespace gmx
AnalysisDataSimpleHistogramModule::~AnalysisDataSimpleHistogramModule()
{
- delete impl_;
}
AnalysisDataWeightedHistogramModule::~AnalysisDataWeightedHistogramModule()
{
- delete impl_;
}
virtual AnalysisDataFrameRef tryGetDataFrameInternal(int index) const;
virtual bool requestStorageInternal(int nframes);
- internal::BasicHistogramImpl *impl_;
+ PrivateImplPointer<internal::BasicHistogramImpl> impl_;
// Copy and assign disallowed by base.
};
virtual AnalysisDataFrameRef tryGetDataFrameInternal(int index) const;
virtual bool requestStorageInternal(int nframes);
- internal::BasicHistogramImpl *impl_;
+ PrivateImplPointer<internal::BasicHistogramImpl> impl_;
// Copy and assign disallowed by base.
};
AbstractPlotModule::~AbstractPlotModule()
{
- delete _impl;
}
#include "../datamodule.h"
#include "../../options/timeunitmanager.h"
+#include "../../utility/common.h"
namespace gmx
{
private:
class Impl;
- Impl *_impl;
-
- // Disallow copy and assign.
- AbstractPlotModule(const AbstractPlotModule &);
- void operator =(const AbstractPlotModule &);
+ PrivateImplPointer<Impl> _impl;
};
MockAnalysisModule::~MockAnalysisModule()
{
- delete impl_;
}
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);
}
#include <gmock/gmock.h>
#include "gromacs/analysisdata/datamodule.h"
+#include "gromacs/utility/common.h"
namespace gmx
{
private:
class Impl;
- Impl *impl_;
+ PrivateImplPointer<Impl> impl_;
};
} // namespace test
MessageStringCollector::~MessageStringCollector()
{
- delete impl_;
}
void MessageStringCollector::startContext(const char *name)
#include <string>
+#include "../utility/common.h"
+
namespace gmx
{
private:
class Impl;
- Impl *impl_;
+ PrivateImplPointer<Impl> impl_;
};
/*! \libinternal \brief
* Adds a context for the given object.
*/
MessageStringContext(MessageStringCollector *collector,
- const std::string &name)
+ const std::string &name)
: collector_(*collector)
{
collector_.startContext(name);
//! The wrapped object.
MessageStringCollector &collector_;
- // Disallow copy and assign.
- MessageStringContext(const MessageStringContext &);
- void operator =(const MessageStringContext &);
+ GMX_DISALLOW_COPY_AND_ASSIGN(MessageStringContext);
};
} // namespace gmx
#include <string>
+#include "../utility/common.h"
+
#include "optionflags.h"
namespace gmx
//! Parent Options object.
Options *_options;
- // Disallow copy and assign.
- AbstractOptionStorage(const AbstractOptionStorage &);
- void operator =(const AbstractOptionStorage &);
+ GMX_DISALLOW_COPY_AND_ASSIGN(AbstractOptionStorage);
};
} // namespace gmx
AsciiHelpWriter::~AsciiHelpWriter()
{
- delete _impl;
}
AsciiHelpWriter &AsciiHelpWriter::setShowHidden(bool bSet)
#include <cstdio>
+#include "../utility/common.h"
+
namespace gmx
{
private:
class Impl;
- Impl *_impl;
-
- // Disallow copy and assign.
- AsciiHelpWriter(const AsciiHelpWriter &);
- void operator =(const AsciiHelpWriter &);
+ PrivateImplPointer<Impl> _impl;
};
} // namespace gmx
CommandLineParser::~CommandLineParser()
{
- delete _impl;
}
void CommandLineParser::parse(int *argc, char *argv[])
#ifndef GMX_OPTIONS_CMDLINEPARSER_H
#define GMX_OPTIONS_CMDLINEPARSER_H
+#include "../utility/common.h"
+
namespace gmx
{
private:
class Impl;
- Impl *_impl;
-
- // Disallow copy and assign.
- CommandLineParser(const CommandLineParser &);
- void operator =(const CommandLineParser &);
+ PrivateImplPointer<Impl> _impl;
};
} // namespace gmx
#include <string>
+#include "../utility/common.h"
+
namespace gmx
{
//! The wrapped option.
AbstractOptionStorage &_option;
- // Disallow copy and assign.
- OptionInfo(const OptionInfo &);
- void operator =(const OptionInfo &);
+ GMX_DISALLOW_COPY_AND_ASSIGN(OptionInfo);
};
} // namespace gmx
Options::~Options()
{
- delete _impl;
}
const std::string &Options::name() const
#include <string>
+#include "../utility/common.h"
+
namespace gmx
{
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;
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
OptionsAssigner::~OptionsAssigner()
{
- delete _impl;
}
void OptionsAssigner::setAcceptBooleanNoPrefix(bool enabled)
#include <string>
+#include "../utility/common.h"
+
namespace gmx
{
private:
class Impl;
- Impl *_impl;
-
- // Disallow copy and assign.
- OptionsAssigner(const OptionsAssigner &);
- void operator =(const OptionsAssigner &);
+ PrivateImplPointer<Impl> _impl;
};
} // namespace gmx
#include <string>
+#include "../utility/common.h"
+
#include "optioninfo.h"
namespace gmx
//! 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
//! 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
#include "../fatalerror/gmxassert.h"
#include "../utility/arrayref.h"
+#include "../utility/common.h"
#include "position.h"
#include "indexutil.h"
*/
friend class SelectionPosition;
- // Disallow copy and assign.
- Selection(const Selection &);
- void operator =(const Selection &);
+ GMX_DISALLOW_COPY_AND_ASSIGN(Selection);
};
/*! \brief
SelectionCollection::~SelectionCollection()
{
- delete _impl;
}
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");
}
#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;
private:
class Impl;
- Impl *_impl;
+ PrivateImplPointer<Impl> _impl;
/*! \brief
* Needed for the compiler to freely modify the collection.
* Needed for handling delayed selection parsing requests.
*/
friend class SelectionOptionStorage;
-
- // Disallow copy and assign.
- SelectionCollection(const SelectionCollection &);
- void operator =(const SelectionCollection &);
};
} // namespace gmx
TrajectoryAnalysisModuleData::~TrajectoryAnalysisModuleData()
{
- delete _impl;
}
TrajectoryAnalysisModule::~TrajectoryAnalysisModule()
{
- delete _impl;
}
{
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;
}
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);
}
#include "../legacyheaders/typedefs.h"
+#include "../utility/common.h"
+
namespace gmx
{
private:
class Impl;
- Impl *_impl;
-
- // Disallow copy and assign.
- TrajectoryAnalysisModuleData(const TrajectoryAnalysisModuleData &);
- void operator =(const TrajectoryAnalysisModuleData &);
+ PrivateImplPointer<Impl> _impl;
};
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
TrajectoryAnalysisSettings::~TrajectoryAnalysisSettings()
{
- delete _impl;
}
#include "../legacyheaders/typedefs.h"
#include "../options/timeunitmanager.h"
+#include "../utility/common.h"
namespace gmx
{
private:
class Impl;
- Impl *_impl;
-
- // Disallow copy and assign.
- TrajectoryAnalysisSettings(const TrajectoryAnalysisSettings &);
- void operator =(const TrajectoryAnalysisSettings &);
+ PrivateImplPointer<Impl> _impl;
friend class TrajectoryAnalysisRunnerCommon;
};
//! 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;
};
TrajectoryAnalysisCommandLineRunner::~TrajectoryAnalysisCommandLineRunner()
{
- delete _impl;
}
#ifndef GMX_TRAJECTORYANALYSIS_CMDLINERUNNER_H
#define GMX_TRAJECTORYANALYSIS_CMDLINERUNNER_H
+#include "../utility/common.h"
+
namespace gmx
{
private:
class Impl;
- Impl *_impl;
-
- // Disallow copy and assign.
- TrajectoryAnalysisCommandLineRunner(const TrajectoryAnalysisCommandLineRunner &);
- void operator =(const TrajectoryAnalysisCommandLineRunner &);
+ PrivateImplPointer<Impl> _impl;
};
} // namespace gmx
TrajectoryAnalysisRunnerCommon::~TrajectoryAnalysisRunnerCommon()
{
- delete _impl;
}
#ifndef GMX_TRAJECTORYANALYSIS_RUNNERCOMMON_H
#define GMX_TRAJECTORYANALYSIS_RUNNERCOMMON_H
-#include <typedefs.h>
+#include "../utility/common.h"
namespace gmx
{
private:
class Impl;
- Impl *_impl;
-
- // Disallow copy and assign.
- TrajectoryAnalysisRunnerCommon(const TrajectoryAnalysisRunnerCommon &);
- void operator =(const TrajectoryAnalysisRunnerCommon &);
+ PrivateImplPointer<Impl> _impl;
};
} // namespace gmx
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)
--- /dev/null
+/*
+ *
+ * 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
TestReferenceData::~TestReferenceData()
{
- delete _impl;
}
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;
}
#include <iterator>
#include <string>
+#include "gromacs/utility/common.h"
+
namespace gmx
{
namespace test
private:
class Impl;
- Impl *_impl;
-
- // Disallow copy and assign.
- TestReferenceData(const TestReferenceData &);
- void operator =(const TestReferenceData &);
+ PrivateImplPointer<Impl> _impl;
};
/*! \libinternal \brief
*/
explicit TestReferenceChecker(Impl *impl);
- Impl *_impl;
+ PrivateImplPointer<Impl> _impl;
/*! \brief
* Needed to expose the constructor only to TestReferenceData.