gmx_test_inline_asm_gcc_x86(GMX_X86_GCC_INLINE_ASM)
gmx_test_inline_asm_msvc_x86(GMX_X86_MSVC_INLINE_ASM)
+include(gmxTestCXX11)
+gmx_test_cxx11(HAVE_CXX11 CXX11_FLAG)
+set(GROMACS_CXX_FLAGS "${CXX11_FLAG} ${GROMACS_CXX_FLAGS}")
+
# turn on SSE if supported with reasonable defaults.
if (${GMX_ACCELERATION} STREQUAL "auto" AND NOT GMX_OPENMM)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(i.86|x86|x64|x86_64|AMD64|amd64)" OR CYGWIN)
if (CMAKE_CXX_COMPILER_ID MATCHES "Intel")
if (NOT WIN32)
- GMX_TEST_CXXFLAG(CXXFLAGS_OPT "-std=gnu99" GMXC_CXXFLAGS)
GMX_TEST_CXXFLAG(CXXFLAGS_OPT "-ip -funroll-all-loops" GMXC_CXXFLAGS_RELEASE)
GMX_TEST_CXXFLAG(CXXFLAGS_SSE2 "-msse2" GMXC_CXXFLAGS_RELEASE)
GMX_TEST_CXXFLAG(CXXFLAGS_X86 "-mtune=core2" GMXC_CXXFLAGS_RELEASE)
--- /dev/null
+include(CheckCXXSourceCompiles)
+MACRO(GMX_TEST_CXX11 VARIABLE FLAG)
+ MESSAGE(STATUS "Checking for C++11 support")
+ if(NOT WIN32)
+ set(CXX11_FLAG "-std=c++0x")
+ else()
+ set(CXX11_FLAG "/Qstd=c++0x")
+ endif()
+ CHECK_CXX_COMPILER_FLAG("${CXX11_FLAG}" CXXFLAG_STD_CXX0X)
+ if(NOT CXXFLAG_STD_CXX0X)
+ set(CXX11_FLAG "")
+ endif()
+ set(CMAKE_REQUIRED_DEFINITIONS "${CXX11_FLAG}")
+ check_cxx_source_compiles(
+"#include <vector>
+#include <memory>
+#include <utility>
+struct A {
+ std::unique_ptr<int> p;
+};
+int main() {
+ typedef std::unique_ptr<int> intPointer;
+ intPointer p(new int(10));
+ std::vector<intPointer> v;
+ v.push_back(std::move(p));
+ std::vector<A> v2;
+ v2.push_back(A()); //requires default move constructor
+}" CXX11_SUPPORT_OK)
+ set(CMAKE_REQUIRED_DEFINITIONS "")
+ if(CXX11_SUPPORT_OK)
+ set(${VARIABLE} ${CXX11_SUPPORT_OK})
+ set(${FLAG} ${CXX11_FLAG})
+ MESSAGE(STATUS "Checking for C++11 support - yes")
+ else()
+ set(${FLAG} "")
+ MESSAGE(STATUS "Checking for C++11 support - no")
+ endif()
+ENDMACRO()
\ No newline at end of file
*
* For more info, check our website at http://www.gromacs.org
*/
-#include <memory>
#include <string>
#include <vector>
class AnalysisTemplate::ModuleData : public TrajectoryAnalysisModuleData
{
public:
+ /*! \brief
+ * Initializes frame-local data.
+ *
+ * \param[in] module Analysis module to use for data objects.
+ * \param[in] opt Data parallelization options.
+ * \param[in] selections Thread-local selection collection.
+ * \param[in] cutoff Cutoff distance for the search
+ * (<=0 stands for no cutoff).
+ * \param[in] posCount Maximum number of reference particles.
+ */
ModuleData(TrajectoryAnalysisModule *module,
const AnalysisDataParallelOptions &opt,
- const SelectionCollection &selections)
+ const SelectionCollection &selections,
+ double cutoff, int posCount)
: TrajectoryAnalysisModuleData(module, opt, selections),
- _nb(NULL)
+ _nb(cutoff, posCount)
{
}
- virtual ~ModuleData()
- {
- delete _nb;
- }
-
virtual void finish()
{
finishDataHandles();
}
- NeighborhoodSearch *_nb;
+ //! Neighborhood search data for distance calculation.
+ NeighborhoodSearch _nb;
};
"To get started with implementing your own analysis program,",
"follow the instructions in the README file provided.",
"This template implements a simple analysis programs that calculates",
- "average distances from the a reference group to one or more",
+ "average distances from a reference group to one or more",
"analysis groups.",
NULL
};
AnalysisTemplate::startFrames(const AnalysisDataParallelOptions &opt,
const SelectionCollection &selections)
{
- std::auto_ptr<ModuleData> pdata(new ModuleData(this, opt, selections));
- pdata->_nb = new NeighborhoodSearch(_cutoff, _refsel->posCount());
- return pdata.release();
+ return new ModuleData(this, opt, selections, _cutoff, _refsel->posCount());
}
TrajectoryAnalysisModuleData *pdata)
{
AnalysisDataHandle *dh = pdata->dataHandle("avedist");
- NeighborhoodSearch *nb = static_cast<ModuleData *>(pdata)->_nb;
+ NeighborhoodSearch &nb = static_cast<ModuleData *>(pdata)->_nb;
- nb->init(pbc, _refsel->positions());
+ nb.init(pbc, _refsel->positions());
dh->startFrame(frnr, fr.time);
for (size_t g = 0; g < _sel.size(); ++g)
{
for (int i = 0; i < nr; ++i)
{
SelectionPosition p = sel->position(i);
- frave += nb->minimumDistance(p.x());
+ frave += nb.minimumDistance(p.x());
}
frave /= nr;
dh->setPoint(g, frave);
/* Define if we have pipes */
#cmakedefine HAVE_PIPES
+/* Define if we have sufficient C++11 support */
+#cmakedefine HAVE_CXX11
/* Catch stupid CMake problems on OS X */
#ifdef __APPLE__
#include <vector>
-#include "types/simple.h"
+#include "../legacyheaders/types/simple.h"
+
+#include "gromacs/utility/uniqueptr.h"
#include "abstractdata.h"
#include "dataframe.h"
class AbstractAnalysisData::Impl
{
public:
+ //! Shorthand for a smart pointer to a module.
+ typedef gmx_unique_ptr<AnalysisDataModuleInterface>::type ModulePointer;
//! Shorthand for list of modules added to the data.
- typedef std::vector<AnalysisDataModuleInterface *> ModuleList;
+ typedef std::vector<ModulePointer> ModuleList;
Impl();
~Impl();
AbstractAnalysisData::Impl::~Impl()
{
- ModuleList::const_iterator i;
- for (i = _modules.begin(); i != _modules.end(); ++i)
- {
- delete *i;
- }
}
void
AbstractAnalysisData::addModule(AnalysisDataModuleInterface *module)
{
- std::auto_ptr<AnalysisDataModuleInterface> module_ptr(module);
+ Impl::ModulePointer module_ptr(module);
if ((columnCount() > 1 && !(module->flags() & AnalysisDataModuleInterface::efAllowMulticolumn))
|| (isMultipoint() && !(module->flags() & AnalysisDataModuleInterface::efAllowMultipoint))
|| (!isMultipoint() && (module->flags() & AnalysisDataModuleInterface::efOnlyMultipoint)))
{
_impl->_bAllowMissing = false;
}
- _impl->_modules.push_back(module);
- module_ptr.release();
+ _impl->_modules.push_back(move(module_ptr));
}
#include <vector>
+#include "gromacs/utility/uniqueptr.h"
+
#include "analysisdata.h"
#include "datastorage.h"
class AnalysisData::Impl
{
public:
+ //! Shorthand for a smart pointer to a data handle.
+ typedef gmx_unique_ptr<AnalysisDataHandle>::type HandlePointer;
//! Shorthand for a list of data handles.
- typedef std::vector<AnalysisDataHandle *> HandleList;
+ typedef std::vector<HandlePointer> HandleList;
Impl();
~Impl();
*/
#include "gromacs/analysisdata/analysisdata.h"
-#include <algorithm>
-#include <memory>
-
#include "gromacs/analysisdata/dataframe.h"
#include "gromacs/analysisdata/datastorage.h"
#include "gromacs/analysisdata/paralleloptions.h"
AnalysisData::Impl::~Impl()
{
- HandleList::const_iterator i;
- for (i = handles_.begin(); i != handles_.end(); ++i)
- {
- delete *i;
- }
}
GMX_THROW(NotImplementedError("Parallelism not supported for multipoint data"));
}
- std::auto_ptr<AnalysisDataHandle> handle(new AnalysisDataHandle(this));
- impl_->handles_.push_back(handle.get());
- return handle.release();
+ Impl::HandlePointer handle(new AnalysisDataHandle(this));
+ impl_->handles_.push_back(move(handle));
+ return impl_->handles_.back().get();
}
{
Impl::HandleList::iterator i;
- i = std::find(impl_->handles_.begin(), impl_->handles_.end(), handle);
+ for (i = impl_->handles_.begin(); i != impl_->handles_.end(); ++i)
+ {
+ if (i->get() == handle)
+ {
+ break;
+ }
+ }
GMX_RELEASE_ASSERT(i != impl_->handles_.end(),
"finishData() called for an unknown handle");
impl_->handles_.erase(i);
- delete handle;
if (impl_->handles_.empty())
{
#include <limits>
#include <vector>
+#include "gromacs/utility/uniqueptr.h"
+
#include "datastorage.h"
namespace gmx
class AnalysisDataStorage::Impl
{
public:
+ //! Smart pointer type for managing a stored frame.
+ typedef gmx_unique_ptr<AnalysisDataStorageFrame>::type FramePointer;
+
/*! \brief
* Stored information about a single stored frame.
*/
struct StoredFrame
{
+ //! Indicates what operations have been performed on a frame.
enum Status
{
eMissing, //!< Frame has not yet been started.
eNotified //!< Appropriate notifications have been sent.
};
- StoredFrame() : frame(NULL), status(eMissing) {}
+ //! Constructs an object that manages a given frame object.
explicit StoredFrame(AnalysisDataStorageFrame *frame)
: frame(frame), status(eMissing)
{
}
-
+ //! Whether the frame has been started with startFrame().
bool isStarted() const { return status >= eStarted; }
+ //! Whether the frame has been finished with finishFrame().
bool isFinished() const { return status >= eFinished; }
+ //! Whether all notifications have been sent.
bool isNotified() const { return status >= eNotified; }
+ //! Whether the frame is ready to be available outside the storage.
bool isAvailable() const { return status >= eFinished; }
/*! \brief
* Actual frame data.
*
- * Always allocated. Memory is managed by the parent Impl object
- * to make the StoredFrame type STL-container-friendly.
+ * Never NULL.
*/
- AnalysisDataStorageFrame *frame;
+ FramePointer frame;
//! In what state the frame currently is.
Status status;
};
AnalysisDataStorage::Impl::~Impl()
{
- FrameList::const_iterator i;
- for (i = frames_.begin(); i != frames_.end(); ++i)
- {
- delete i->frame;
- }
}
{
return AnalysisDataFrameRef();
}
- const AnalysisDataStorageFrame *frame = storedFrame.frame;
+ const Impl::FramePointer &frame = storedFrame.frame;
return AnalysisDataFrameRef(frame->header(), frame->values_);
}
class AnalysisDataStorageFrame
{
public:
+ /*! \brief Frees the frame object.
+ *
+ * Should not be called outside AnalysisDataStorage.
+ */
+ ~AnalysisDataStorageFrame();
+
//! Returns header for the frame.
const AnalysisDataFrameHeader &header() const { return header_; }
//! Returns zero-based index of the frame.
*/
AnalysisDataStorageFrame(AnalysisDataStorage *storage, int columnCount,
int index);
- ~AnalysisDataStorageFrame();
//! Clear all column values from the frame.
void clearValues();
* \author Teemu Murtola <teemu.murtola@cbr.su.se>
* \ingroup module_analysisdata
*/
-#include <memory>
-
#include <gtest/gtest.h>
#include "gromacs/analysisdata/arraydata.h"
#include "mock_module.h"
-#include <memory>
+#include <boost/scoped_ptr.hpp>
namespace gmx
{
class MockAnalysisModule::Impl
{
public:
+ //! Initializes a mock object with the given flags.
explicit Impl(int flags);
+ /*! \brief
+ * Callback used to check frame start against reference data.
+ *
+ * Called to check parameters and order of calls to frameStarted().
+ * In addition to reference data checks, this method checks statically
+ * that the new frame matches \a frameIndex_.
+ */
void startReferenceFrame(const AnalysisDataFrameHeader &header);
+ /*! \brief
+ * Callback used to check frame points against reference data.
+ *
+ * Called to check parameters and order of calls to pointsAdded().
+ */
void checkReferencePoints(const AnalysisDataPointSetRef &points);
+ /*! \brief
+ * Callback used to check frame finish against reference data.
+ *
+ * Called to check parameters and order of calls to frameFinished().
+ * \a frameIndex_ is incremented here.
+ */
void finishReferenceFrame(const AnalysisDataFrameHeader &header);
- // Could be scoped_ptrs
- std::auto_ptr<TestReferenceChecker> rootChecker_;
- std::auto_ptr<TestReferenceChecker> frameChecker_;
+ /*! \brief
+ * Reference data checker to use for checking frames.
+ *
+ * Must be non-NULL if startReferenceFrame() is called.
+ */
+ boost::scoped_ptr<TestReferenceChecker> rootChecker_;
+ /*! \brief
+ * Reference data checker to use to check the current frame.
+ *
+ * Non-NULL between startReferenceFrame() and finishReferenceFrame()
+ * calls.
+ */
+ boost::scoped_ptr<TestReferenceChecker> frameChecker_;
+ //! Flags that will be returned by the mock module.
int flags_;
+ //! Index of the current/next frame.
int frameIndex_;
};
}
}
-}
+} // namespace
MockAnalysisModule::Impl::Impl(int flags)
: flags_(flags), frameIndex_(0)
void
MockAnalysisModule::Impl::startReferenceFrame(const AnalysisDataFrameHeader &header)
{
+ GMX_RELEASE_ASSERT(rootChecker_.get() != NULL,
+ "Root checker not set, but reference data used");
EXPECT_TRUE(frameChecker_.get() == NULL);
EXPECT_EQ(frameIndex_, header.index());
frameChecker_.reset(new TestReferenceChecker(
#ifndef GMX_OPTIONS_OPTIONS_IMPL_H
#define GMX_OPTIONS_OPTIONS_IMPL_H
-#include <memory>
#include <string>
#include <vector>
+#include "gromacs/utility/uniqueptr.h"
+
#include "options.h"
namespace gmx
class Options::Impl
{
public:
+ //! Shorthand for a smart pointer to an option storage object.
+ typedef gmx_unique_ptr<AbstractOptionStorage>::type OptionPointer;
//! Convenience type for list of sections.
typedef std::vector<Options *> SubSectionList;
//! Convenience type for list of options.
- typedef std::vector<AbstractOptionStorage *> OptionList;
+ typedef std::vector<OptionPointer> OptionList;
//! Sets the name and title.
Impl(const char *name, const char *title);
Options::Impl::~Impl()
{
- OptionList::const_iterator i;
- for (i = _options.begin(); i != _options.end(); ++i)
- {
- delete *i;
- }
}
Options *Options::Impl::findSubSection(const char *name) const
{
if ((*i)->name() == name)
{
- return *i;
+ return i->get();
}
}
return NULL;
OptionList::const_iterator i;
for (i = _options.begin(); i != _options.end(); ++i)
{
- AbstractOptionStorage *option = *i;
- option->startSource();
+ AbstractOptionStorage &option = **i;
+ option.startSource();
}
SubSectionList::const_iterator j;
for (j = _subSections.begin(); j != _subSections.end(); ++j)
{
- Options *section = *j;
- section->_impl->startSource();
+ Options §ion = **j;
+ section._impl->startSource();
}
}
void Options::addOption(const AbstractOption &settings)
{
- std::auto_ptr<AbstractOptionStorage> option(settings.createDefaultStorage(this));
+ Impl::OptionPointer option(settings.createDefaultStorage(this));
if (_impl->findOption(option->name().c_str()) != NULL)
{
GMX_THROW(APIError("Duplicate option: " + option->name()));
}
- _impl->_options.push_back(option.get());
- option.release();
+ _impl->_options.push_back(move(option));
}
bool Options::isSet(const char *name) const
Impl::OptionList::const_iterator i;
for (i = _impl->_options.begin(); i != _impl->_options.end(); ++i)
{
- AbstractOptionStorage *option = *i;
+ AbstractOptionStorage &option = **i;
try
{
- option->finish();
+ option.finish();
}
catch (const UserInputError &ex)
{
- MessageStringContext context(&errors, "In option " + option->name());
+ MessageStringContext context(&errors, "In option " + option.name());
errors.append(ex.what());
}
}
Impl::SubSectionList::const_iterator j;
for (j = _impl->_subSections.begin(); j != _impl->_subSections.end(); ++j)
{
- Options *section = *j;
+ Options §ion = **j;
try
{
- section->finish();
+ section.finish();
}
catch (const UserInputError &ex)
{
#ifndef GMX_OPTIONS_OPTIONSTORAGETEMPLATE_H
#define GMX_OPTIONS_OPTIONSTORAGETEMPLATE_H
-#include <memory>
#include <string>
#include <vector>
+#include <boost/scoped_ptr.hpp>
+
#include "../fatalerror/exceptions.h"
#include "../fatalerror/gmxassert.h"
ValueList *_values;
T *_store;
int *_countptr;
- // Could be scoped_ptr
- std::auto_ptr<T> _defaultValueIfSet;
+ boost::scoped_ptr<ValueList> _ownedValues;
+ boost::scoped_ptr<T> _defaultValueIfSet;
// Copy and assign disallowed by base.
};
_store(settings._store),
_countptr(settings._countptr)
{
- std::auto_ptr<std::vector<T> > valueGuard;
- if (!_values)
+ if (_values == NULL)
{
// The flag should be set for proper error checking.
GMX_RELEASE_ASSERT(!hasFlag(efExternalValueVector),
"Internal inconsistency");
- valueGuard.reset(new std::vector<T>);
- _values = valueGuard.get();
+ _ownedValues.reset(new std::vector<T>);
+ _values = _ownedValues.get();
}
if (hasFlag(efNoDefaultValue)
&& (settings._defaultValue != NULL
// TODO: This is a bit hairy, as it indirectly calls a virtual function.
commitValues();
}
- else if (!hasFlag(efExternalValueVector) && _store != NULL)
+ else if (_ownedValues.get() == NULL && _store != NULL)
{
_values->clear();
int count = (settings.isVector() ?
}
}
setFlag(efClearOnNextSet);
- valueGuard.release();
}
template <typename T>
OptionStorageTemplate<T>::~OptionStorageTemplate()
{
- if (!hasFlag(efExternalValueVector))
- {
- delete _values;
- }
}
*/
for (i = 0; i < sc->sel.size(); ++i)
{
- gmx::Selection *sel = sc->sel[i];
+ gmx::Selection *sel = sc->sel[i].get();
init_pos_keyword_defaults(sel->rootElement_,
coll->_impl->_spost.c_str(),
coll->_impl->_rpost.c_str(),
sel = sel->next;
}
/* Update selection information */
- std::vector<Selection *>::iterator isel;
+ SelectionList::const_iterator isel;
for (isel = sc->sel.begin(); isel != sc->sel.end(); ++isel)
{
- Selection *sel = *isel;
-
- sel->refreshMassesAndCharges();
- sel->updateCoveredFractionForFrame();
+ Selection &sel = **isel;
+ sel.refreshMassesAndCharges();
+ sel.updateCoveredFractionForFrame();
}
}
{
gmx_ana_selcollection_t *sc = &coll->_impl->_sc;
- std::vector<Selection *>::iterator isel;
+ SelectionList::const_iterator isel;
for (isel = sc->sel.begin(); isel != sc->sel.end(); ++isel)
{
- Selection *sel = *isel;
- sel->restoreOriginalPositions();
- sel->computeAverageCoveredFraction(nframes);
+ Selection &sel = **isel;
+ sel.restoreOriginalPositions();
+ sel.computeAverageCoveredFraction(nframes);
}
}
#include <stdio.h>
#include <stdarg.h>
-#include <memory>
-
#include <futil.h>
#include <smalloc.h>
#include <string2.h>
/* Add the new selection to the collection if it is not a variable. */
if (sel->child->type != SEL_SUBEXPR)
{
- std::auto_ptr<gmx::Selection> newsel(
- new gmx::Selection(sel, _gmx_sel_lexer_pselstr(scanner)));
- sc->sel.push_back(newsel.get());
- newsel.release();
+ gmx::SelectionPointer selPtr(
+ new gmx::Selection(sel, _gmx_sel_lexer_pselstr(scanner)));
+ sc->sel.push_back(move(selPtr));
}
}
/* Clear the selection string now that we've saved it */
#include <string>
#include <vector>
-#include <typedefs.h>
+#include "../legacyheaders/typedefs.h"
+
+#include "gromacs/utility/uniqueptr.h"
#include "../options/options.h"
#include "../utility/flags.h"
namespace gmx
{
class Selection;
+
+//! Smart pointer for managing a selection.
+typedef gmx_unique_ptr<Selection>::type SelectionPointer;
+//! Shorthand for storing a list of selections internally.
+typedef std::vector<SelectionPointer> SelectionList;
}
/*! \internal \brief
/** Root of the selection element tree. */
struct t_selelem *root;
/** Array of compiled selections. */
- std::vector<gmx::Selection *> sel;
+ gmx::SelectionList sel;
/** Number of variables defined. */
int nvars;
/** Selection strings for variables. */
SelectionOptionStorage *storage;
};
- //! Shorthand for a list of selections stored internally.
- typedef std::vector<Selection *> SelectionList;
//! Shorthand for a list of selection requests.
typedef std::vector<SelectionRequest> RequestList;
SelectionCollection::Impl::~Impl()
{
_gmx_selelem_free_chain(_sc.root);
- SelectionList::const_iterator isel;
- for (isel = _sc.sel.begin(); isel != _sc.sel.end(); ++isel)
- {
- delete *isel;
- }
+ _sc.sel.clear();
for (int i = 0; i < _sc.nvars; ++i)
{
sfree(_sc.varstrs[i]);
SelectionList::const_iterator i;
for (i = _sc.sel.begin() + oldCount; i != _sc.sel.end(); ++i)
{
- output->push_back(*i);
+ output->push_back(i->get());
}
}
set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${UTILITY_SOURCES} PARENT_SCOPE)
set(UTILITY_PUBLIC_HEADERS
- arrayref.h common.h flags.h format.h)
+ arrayref.h common.h flags.h format.h uniqueptr.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 gmx::gmx_unique_ptr and supporting functionality.
+ *
+ * \author Roland Schulz <roland@utk.edu>
+ * \author John Eblen <jeblen@acm.org>
+ * \inlibraryapi
+ * \ingroup module_utility
+ */
+#ifndef GMX_UTILITY_UNIQUEPTR_H
+#define GMX_UTILITY_UNIQUEPTR_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_CXX11 // C++11 Compiler
+#include <memory>
+#include <utility>
+#else // C++03 Compiler
+#include <boost/shared_ptr.hpp>
+#endif
+
+namespace gmx
+{
+
+/*! \class gmx_unique_ptr
+ * \brief
+ * Smart pointer for unique ownership.
+ *
+ * The \a type member typedef declares the actual smart pointer type.
+ * If std::unique_ptr from C++11 is available, it is used, otherwise maps to
+ * boost::shared_ptr. Because of this, there are some limitations to usage.
+ * gmx::move() should be used to move the pointer.
+ *
+ * Avoid using directly as a type, use a typedef instead. Typical usage:
+ * \code
+typedef gmx_unique_ptr<ExampleClass>::type ExampleClassPointer;
+ * \endcode
+ *
+ * \ingroup module_utility
+ * \inlibraryapi
+ */
+
+/*! \typedef gmx_unique_ptr::type
+ * \brief The smart pointer type.
+ * Work-around for the non-existence of template typedefs in C++03.
+ */
+
+/*! \fn boost::shared_ptr<T> &move(boost::shared_ptr<T> &ptr)
+ * \brief Moves gmx::gmx_unique_ptr type pointers
+ * For C++11 gmx::move is the std::move, for non-C++11 compilers, the
+ * move operation is a no-op.
+ *
+ * \ingroup module_utility
+ * \inlibraryapi
+ */
+#ifdef HAVE_CXX11 // C++11 Compiler
+using std::move;
+template<typename T>
+struct gmx_unique_ptr
+{
+ typedef std::unique_ptr<T> type;
+};
+#else // C++03 Compiler
+template<typename T>
+boost::shared_ptr<T> &move(boost::shared_ptr<T> &ptr)
+{
+ return ptr;
+}
+template<typename T>
+struct gmx_unique_ptr
+{
+ typedef boost::shared_ptr<T> type;
+};
+#endif
+
+} // namespace gmx
+
+#endif