# To help us fund GROMACS development, we humbly ask that you cite
# the research papers on the package. Check out http://www.gromacs.org.
-file(GLOB OPTIONS_SOURCES *.cpp)
-set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${OPTIONS_SOURCES} PARENT_SCOPE)
+gmx_add_libgromacs_sources(
+ abstractoption.cpp
+ abstractsection.cpp
+ basicoptions.cpp
+ behaviorcollection.cpp
+ filenameoption.cpp
+ filenameoptionmanager.cpp
+ options.cpp
+ optionsassigner.cpp
+ optionsvisitor.cpp
+ timeunitmanager.cpp
+ )
gmx_install_headers(
abstractoption.h
+ abstractsection.h
basicoptions.h
filenameoption.h
filenameoptionmanager.h
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2016, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, 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 http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * Implements classes from abstractsection.h.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \ingroup module_options
+ */
+#include "gmxpre.h"
+
+#include "abstractsection.h"
+
+#include "options-impl.h"
+
+namespace gmx
+{
+
+IOptionsContainer &AbstractOptionSectionHandle::addGroup()
+{
+ return section_->addGroup();
+}
+
+internal::OptionSectionImpl *
+AbstractOptionSectionHandle::addSectionImpl(const AbstractOptionSection §ion)
+{
+ return section_->addSectionImpl(section);
+}
+
+OptionInfo *AbstractOptionSectionHandle::addOptionImpl(const AbstractOption &settings)
+{
+ return section_->addOptionImpl(settings);
+}
+
+} // namespace gmx
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2016, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, 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 http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \file
+ * \brief
+ * Declares base classes for declaring option sections.
+ *
+ * This header defines base classes for option section settings that are used
+ * with IOptionsContainerWithSections::addSection(). These classes implement
+ * the "named parameter" idiom for specifying section properties.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \ingroup module_options
+ */
+#ifndef GMX_OPTIONS_ABSTRACTSECTION_H
+#define GMX_OPTIONS_ABSTRACTSECTION_H
+
+#include "gromacs/options/ioptionscontainerwithsections.h"
+#include "gromacs/utility/classhelpers.h"
+
+namespace gmx
+{
+
+namespace internal
+{
+class OptionSectionImpl;
+}
+
+/*! \brief
+ * Base class for specifying option section properties.
+ *
+ * \ingroup module_options
+ */
+class AbstractOptionSection
+{
+ protected:
+ //! \cond libapi
+ //! Initializes option properties with the given name.
+ explicit AbstractOptionSection(const char *name) : name_(name) {}
+ //! \endcond
+
+ private:
+ const char *name_;
+
+ friend class internal::OptionSectionImpl;
+};
+
+/*! \brief
+ * Base class for handles to option sections.
+ *
+ * This class implements the common functionality for adding options and
+ * subsections to option sections.
+ *
+ * \ingroup module_options
+ */
+class AbstractOptionSectionHandle : public IOptionsContainerWithSections
+{
+ public:
+ // From IOptionsContainer
+ //! \copydoc IOptionsContainer::addGroup()
+ virtual IOptionsContainer &addGroup();
+
+ protected:
+ //! \cond libapi
+ //! Wraps a given section storage object.
+ explicit AbstractOptionSectionHandle(internal::OptionSectionImpl *section)
+ : section_(section)
+ {
+ }
+ //! \endcond
+
+ private:
+ // From IOptionsContainerWithSections
+ virtual internal::OptionSectionImpl *
+ addSectionImpl(const AbstractOptionSection §ion);
+ // From IOptionsContainer
+ virtual OptionInfo *addOptionImpl(const AbstractOption &settings);
+
+ internal::OptionSectionImpl *section_;
+};
+
+class AbstractOptionSectionInfo
+{
+ public:
+ //! Wraps a given section storage object.
+ explicit AbstractOptionSectionInfo(internal::OptionSectionImpl *section)
+ : section_(*section)
+ {
+ }
+
+ //! Returns the wrapped section storage object.
+ internal::OptionSectionImpl §ion() { return section_; }
+ //! Returns the wrapped section storage object.
+ const internal::OptionSectionImpl §ion() const { return section_; }
+
+ private:
+ internal::OptionSectionImpl §ion_;
+
+ GMX_DISALLOW_COPY_AND_ASSIGN(AbstractOptionSectionInfo);
+};
+
+} // namespace gmx
+
+#endif
* output.
*/
virtual IOptionsContainer &addGroup() = 0;
- /*! \brief
- * Adds a recognized option.
- *
- * \param[in] settings Option description.
- * \returns OptionInfo object for the created option (never NULL).
- * \throws APIError if invalid option settings are provided.
- *
- * This method provides the internal implementation, but in most cases
- * the templated method is called from user code.
- * See the templated method for more details.
- */
- virtual OptionInfo *addOption(const AbstractOption &settings) = 0;
/*! \brief
* Adds a recognized option.
*
typename OptionType::InfoType *addOption(const OptionType &settings)
{
OptionInfo *info
- = addOption(static_cast<const AbstractOption &>(settings));
+ = addOptionImpl(static_cast<const AbstractOption &>(settings));
GMX_ASSERT(info->isType<typename OptionType::InfoType>(),
"Mismatching option info type declaration and implementation");
return info->toType<typename OptionType::InfoType>();
// (no need for the virtual, but some compilers warn otherwise)
virtual ~IOptionsContainer();
+ /*! \brief
+ * Adds a recognized option.
+ *
+ * \param[in] settings Option description.
+ * \returns OptionInfo object for the created option (never NULL).
+ * \throws APIError if invalid option settings are provided.
+ *
+ * This method provides the internal implementation, but the templated
+ * method is called from user code. See the templated method for more
+ * details.
+ */
+ virtual OptionInfo *addOptionImpl(const AbstractOption &settings) = 0;
+
GMX_DEFAULT_CONSTRUCTORS(IOptionsContainer);
};
namespace gmx
{
-class OptionSection;
-class OptionSectionInfo;
+class AbstractOptionSection;
+class AbstractOptionSectionHandle;
+
+namespace internal
+{
+class OptionSectionImpl;
+}
/*! \brief
* Interface for adding input options with sections.
/*! \brief
* Adds a section to this collection.
*
- * \param[in] section Section to add.
+ * \tparam SectionType Type of the section description object.
+ * \param[in] section Section description.
+ * \returns AbstractOptionSectionHandle object for the created option.
+ * \throws APIError if invalid option settings are provided.
+ *
+ * Options can be added to the section through the returned handle.
+ *
+ * \internal
+ * \p SectionType::HandleType must specify a type that derives from
+ * AbstractinOptionSectionHandle and has a suitable constructor.
*/
- virtual IOptionsContainerWithSections &addSection(const OptionSection §ion) = 0;
+ template <class SectionType>
+ typename SectionType::HandleType addSection(const SectionType §ion)
+ {
+ internal::OptionSectionImpl *storage
+ = addSectionImpl(static_cast<const AbstractOptionSection &>(section));
+ return typename SectionType::HandleType(storage);
+ }
protected:
// Disallow deletion through the interface.
// (no need for the virtual, but some compilers warn otherwise)
virtual ~IOptionsContainerWithSections();
+
+ /*! \brief
+ * Adds a section to this container.
+ *
+ * \param[in] section Section description.
+ * \returns Pointer to the internal section representation object.
+ */
+ virtual internal::OptionSectionImpl *
+ addSectionImpl(const AbstractOptionSection §ion) = 0;
+
+ GMX_DEFAULT_CONSTRUCTORS(IOptionsContainerWithSections);
};
} // namespace
// From IOptionsContainer
virtual IOptionsContainer &addGroup();
- virtual OptionInfo *addOption(const AbstractOption &settings);
+ virtual OptionInfo *addOptionImpl(const AbstractOption &settings);
//! Containing options object.
OptionSectionImpl *parent_;
}
// From IOptionsContainerWithSections
- virtual IOptionsContainerWithSections &addSection(const OptionSection §ion);
+ virtual OptionSectionImpl *addSectionImpl(const AbstractOptionSection §ion);
// From IOptionsContainer
virtual IOptionsContainer &addGroup();
- virtual OptionInfo *addOption(const AbstractOption &settings);
+ virtual OptionInfo *addOptionImpl(const AbstractOption &settings);
//! Returns section info object for this section.
OptionSectionInfo &info() { return info_; }
* OptionSectionImpl
*/
-IOptionsContainerWithSections &OptionSectionImpl::addSection(const OptionSection §ion)
+OptionSectionImpl *
+OptionSectionImpl::addSectionImpl(const AbstractOptionSection §ion)
{
const char *name = section.name_;
// Make sure that there are no duplicate sections.
GMX_RELEASE_ASSERT(findSection(name) == NULL, "Duplicate subsection name");
subsections_.push_back(SectionPointer(new OptionSectionImpl(managers_, name)));
- return *subsections_.back();
+ return subsections_.back().get();
}
IOptionsContainer &OptionSectionImpl::addGroup()
return rootGroup_.addGroup();
}
-OptionInfo *OptionSectionImpl::addOption(const AbstractOption &settings)
+OptionInfo *OptionSectionImpl::addOptionImpl(const AbstractOption &settings)
{
- return rootGroup_.addOption(settings);
+ return rootGroup_.addOptionImpl(settings);
}
OptionSectionImpl *OptionSectionImpl::findSection(const char *name) const
return subgroups_.back();
}
-OptionInfo *OptionSectionImpl::Group::addOption(const AbstractOption &settings)
+OptionInfo *OptionSectionImpl::Group::addOptionImpl(const AbstractOption &settings)
{
OptionSectionImpl::AbstractOptionStoragePointer
option(settings.createStorage(parent_->managers_));
impl_->managers_.add(manager);
}
-IOptionsContainerWithSections &Options::addSection(const OptionSection §ion)
+internal::OptionSectionImpl *Options::addSectionImpl(const AbstractOptionSection §ion)
{
- return impl_->rootSection_.addSection(section);
+ return impl_->rootSection_.addSectionImpl(section);
}
IOptionsContainer &Options::addGroup()
return impl_->rootSection_.addGroup();
}
-OptionInfo *Options::addOption(const AbstractOption &settings)
+OptionInfo *Options::addOptionImpl(const AbstractOption &settings)
{
- return impl_->rootSection_.addOption(settings);
+ return impl_->rootSection_.addOptionImpl(settings);
}
OptionSectionInfo &Options::rootSection()
*/
void addManager(IOptionManager *manager);
- // From IOptionsContainerWithSections
- virtual IOptionsContainerWithSections &addSection(const OptionSection §ion);
-
// From IOptionsContainer
virtual IOptionsContainer &addGroup();
- virtual OptionInfo *addOption(const AbstractOption &settings);
- using IOptionsContainer::addOption;
//! Returns a handle to the root section.
OptionSectionInfo &rootSection();
void finish();
private:
+ // From IOptionsContainerWithSections
+ virtual internal::OptionSectionImpl *
+ addSectionImpl(const AbstractOptionSection §ion);
+ // From IOptionsContainer
+ virtual OptionInfo *addOptionImpl(const AbstractOption &settings);
+
PrivateImplPointer<internal::OptionsImpl> impl_;
//! Needed to be able to extend the interface of this object.
#ifndef GMX_OPTIONS_OPTIONSECTION_H
#define GMX_OPTIONS_OPTIONSECTION_H
+#include "gromacs/options/abstractsection.h"
#include "gromacs/utility/classhelpers.h"
namespace gmx
{
-namespace internal
-{
-class OptionSectionImpl;
-}
+class OptionSectionHandle;
-class OptionSection
+/*! \brief
+ * Declares a simple option section.
+ *
+ * This class declares a simple section that only provides structure for
+ * grouping the options, but does not otherwise influence the behavior of the
+ * contained options.
+ *
+ * \inpublicapi
+ * \ingroup module_options
+ */
+class OptionSection : public AbstractOptionSection
{
public:
- explicit OptionSection(const char *name) : name_(name) {}
+ //! AbstractOptionSectionHandle corresponding to this option type.
+ typedef OptionSectionHandle HandleType;
- private:
- const char *name_;
+ //! Creates a section with the given name.
+ explicit OptionSection(const char *name) : AbstractOptionSection(name) {}
+};
- friend class internal::OptionSectionImpl;
+/*! \brief
+ * Allows adding options to an OptionSection.
+ *
+ * An instance of this class is returned from
+ * IOptionsContainerWithSections::addSection(), and supports adding options and
+ * subsections to a section created with OptionSection.
+ *
+ * \inpublicapi
+ * \ingroup module_options
+ */
+class OptionSectionHandle : public AbstractOptionSectionHandle
+{
+ public:
+ //! Wraps a given section storage object.
+ explicit OptionSectionHandle(internal::OptionSectionImpl *section)
+ : AbstractOptionSectionHandle(section)
+ {
+ }
};
-class OptionSectionInfo
+class OptionSectionInfo : public AbstractOptionSectionInfo
{
public:
//! Wraps a given section storage object.
explicit OptionSectionInfo(internal::OptionSectionImpl *section)
- : section_(*section)
+ : AbstractOptionSectionInfo(section)
{
}
-
- //! Returns the wrapped section storage object.
- internal::OptionSectionImpl §ion() { return section_; }
- //! Returns the wrapped section storage object.
- const internal::OptionSectionImpl §ion() const { return section_; }
-
- private:
- internal::OptionSectionImpl §ion_;
-
- GMX_DISALLOW_COPY_AND_ASSIGN(OptionSectionInfo);
};
} // namespace gmx
{
using gmx::OptionSection;
gmx::Options options;
- auto &sub1 = options.addSection(OptionSection("section1"));
- auto &sub2 = options.addSection(OptionSection("section2"));
+ auto sub1 = options.addSection(OptionSection("section1"));
+ auto sub2 = options.addSection(OptionSection("section2"));
int value = 3;
int value1 = 1;
int value2 = 2;