/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,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.
const char *const exportFormats[] = { "rst", "completion" };
std::string exportFormat;
- Options options(NULL, NULL);
+ Options options;
options.addOption(StringOption("export").store(&exportFormat)
.enumValue(exportFormats));
CommandLineParser(&options).parse(&argc, argv);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015,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.
IOptionsFormatter *formatter,
const Options &options);
- virtual void visitSubSection(const Options §ion);
+ virtual void visitSection(const OptionSectionInfo §ion);
virtual void visitOption(const OptionInfo &option);
private:
{
formatter_ = formatter;
filterType_ = type;
- visitSubSection(options);
+ visitSection(options.rootSection());
}
-void OptionsFilter::visitSubSection(const Options §ion)
+void OptionsFilter::visitSection(const OptionSectionInfo §ion)
{
OptionsIterator iterator(section);
- iterator.acceptSubSections(this);
+ iterator.acceptSections(this);
iterator.acceptOptions(this);
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,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.
*/
CommandLineCommonOptionsHolder::CommandLineCommonOptionsHolder()
- : options_(NULL, NULL), bHelp_(false), bHidden_(false),
+ : bHelp_(false), bHidden_(false),
bQuiet_(false), bVersion_(false), bCopyright_(true),
niceLevel_(19), bNiceSet_(false), bBackup_(true), bFpexcept_(false),
debugLevel_(0)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,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.
moduleGuard = factory_();
module = moduleGuard.get();
}
- Options options(name(), shortDescription());
+ Options options;
OptionsBehaviorCollection behaviors(&options);
CommandLineOptionsModuleSettings settings(&behaviors);
module->initOptions(&options, &settings);
void CommandLineOptionsModule::parseOptions(int argc, char *argv[])
{
FileNameOptionManager fileoptManager;
- Options options(name_, description_);
+ Options options;
options.addManager(&fileoptManager);
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,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.
bool bView = false;
int xvgFormat = 0;
gmx::OptionsAdapter adapter(*argc, argv);
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
gmx::OptionsBehaviorCollection behaviors(&options);
gmx::FileNameOptionManager fileOptManager;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,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.
#include "gromacs/fileio/filetypes.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/filenameoption.h"
+#include "gromacs/options/options.h"
#include "gromacs/options/optionsvisitor.h"
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/exceptions.h"
public:
const std::string &optionList() const { return optionList_; }
- virtual void visitSubSection(const Options §ion)
+ virtual void visitSection(const OptionSectionInfo §ion)
{
OptionsIterator iterator(section);
- iterator.acceptSubSections(this);
+ iterator.acceptSections(this);
iterator.acceptOptions(this);
}
virtual void visitOption(const OptionInfo &option)
public:
explicit OptionCompletionWriter(TextWriter *out) : out_(*out) {}
- virtual void visitSubSection(const Options §ion)
+ virtual void visitSection(const OptionSectionInfo §ion)
{
OptionsIterator iterator(section);
- iterator.acceptSubSections(this);
+ iterator.acceptSections(this);
iterator.acceptOptions(this);
}
virtual void visitOption(const OptionInfo &option);
out.writeLine("COMPREPLY=()");
OptionsListWriter listWriter;
- listWriter.visitSubSection(options);
+ listWriter.visitSection(options.rootSection());
out.writeLine(formatString("if (( $COMP_CWORD <= 1 )) || [[ $c == -* ]]; then COMPREPLY=( $(compgen -S ' ' -W $'%s' -- $c)); return 0; fi", listWriter.optionList().c_str()));
out.writeLine("case \"$p\" in");
OptionCompletionWriter optionWriter(&out);
- optionWriter.visitSubSection(options);
+ optionWriter.visitSection(options.rootSection());
out.writeLine("esac }");
}
impl_->file_->writeLine("if (( i == COMP_CWORD )); then");
impl_->file_->writeLine("c=${COMP_WORDS[COMP_CWORD]}");
OptionsListWriter lister;
- lister.visitSubSection(options);
+ lister.visitSection(options.rootSection());
std::string completions(lister.optionList());
for (ModuleNameList::const_iterator i = modules.begin();
i != modules.end(); ++i)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,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.
{
using namespace gmx;
- Options options("test", "Short Description");
+ Options options;
options.addOption(BooleanOption("bool").description("Boolean option")
.defaultValue(true));
options.addOption(BooleanOption("hidden").description("Hidden option")
{
using namespace gmx;
- Options options("test", "Short Description");
+ Options options;
bool bValue = true;
options.addOption(BooleanOption("bool").description("Boolean option")
using gmx::eftGenericData;
using gmx::eftTrajectory;
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
options.addOption(FileNameOption("f")
.description("File name option with a long value")
.filetype(eftTrajectory).inputFile().required()
using gmx::DoubleOption;
using gmx::StringOption;
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
options.addOption(BooleanOption("longboolean")
.description("Boolean option with a long name")
.defaultValue(true));
using gmx::SelectionFileOption;
using gmx::SelectionOption;
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
gmx::SelectionCollection selections;
gmx::SelectionOptionManager manager(&selections);
options.addManager(&manager);
{
using gmx::IntegerOption;
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
gmx::IOptionsContainer &group1 = options.addGroup();
gmx::IOptionsContainer &group2 = options.addGroup();
group2.addOption(IntegerOption("sub2").description("Option in group 2"));
};
using gmx::IntegerOption;
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
options.addOption(IntegerOption("int").description("Integer option")
.defaultValue(2));
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,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.
};
CommandLineParserTest::CommandLineParserTest()
- : options_(NULL, NULL), parser_(&options_),
- flag_(false), ivalue1p_(0), ivalue12_(0)
+ : parser_(&options_), flag_(false), ivalue1p_(0), ivalue12_(0)
{
using gmx::BooleanOption;
using gmx::IntegerOption;
#
# This file is part of the GROMACS molecular simulation package.
#
-# Copyright (c) 2010,2012,2013,2014,2015, by the GROMACS development team, led by
+# Copyright (c) 2010,2012,2013,2014,2015,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.
filenameoptionmanager.h
ioptionsbehavior.h
ioptionscontainer.h
+ ioptionscontainerwithsections.h
optionfiletype.h
optionflags.h
options.h
+ optionsection.h
timeunitmanager.h
)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015,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.
namespace internal
{
-class OptionsImpl;
+class OptionSectionImpl;
}
/*! \brief
*/
friend class AbstractOptionStorage;
//! Needed to be able to call createStorage().
- friend class internal::OptionsImpl;
+ friend class internal::OptionSectionImpl;
};
/*! \brief
--- /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 gmx::IOptionsContainerWithSections.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \inpublicapi
+ * \ingroup module_options
+ */
+#ifndef GMX_OPTIONS_IOPTIONSCONTAINERWITHSECTIONS_H
+#define GMX_OPTIONS_IOPTIONSCONTAINERWITHSECTIONS_H
+
+#include "gromacs/options/ioptionscontainer.h"
+
+namespace gmx
+{
+
+class OptionSection;
+class OptionSectionInfo;
+
+/*! \brief
+ * Interface for adding input options with sections.
+ *
+ * This interface extends IOptionsContainer with an additional addSection()
+ * method that supports creating a hierarchy of sections for the options.
+ *
+ * Header optionsection.h provides OptionSection.
+ *
+ * \inpublicapi
+ * \ingroup module_options
+ */
+class IOptionsContainerWithSections : public IOptionsContainer
+{
+ public:
+ /*! \brief
+ * Adds a section to this collection.
+ *
+ * \param[in] section Section to add.
+ */
+ virtual IOptionsContainerWithSections &addSection(const OptionSection §ion) = 0;
+
+ protected:
+ // Disallow deletion through the interface.
+ // (no need for the virtual, but some compilers warn otherwise)
+ virtual ~IOptionsContainerWithSections();
+};
+
+} // namespace
+
+#endif
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015,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.
#include <vector>
#include "gromacs/options/abstractoption.h"
+#include "gromacs/options/abstractoptionstorage.h"
+#include "gromacs/options/ioptionscontainer.h"
+#include "gromacs/options/ioptionscontainerwithsections.h"
#include "gromacs/options/optionmanagercontainer.h"
#include "gromacs/options/options.h"
+#include "gromacs/options/optionsection.h"
namespace gmx
{
-class AbstractOptionStorage;
+class ExceptionInitializer;
namespace internal
{
/*! \internal
* \brief
- * Private implementation class for Options.
+ * Internal implementation class for storing an option section.
*
- * Note that in addition to Options, the OptionsAssigner and OptionsIterator
- * classes also directly access this class.
+ * All options are stored within a section: the top-level contents of an
+ * Options object are handled within an unnamed, "root" section.
*
* \ingroup module_options
*/
-class OptionsImpl
+class OptionSectionImpl : public IOptionsContainerWithSections
{
public:
/*! \internal \brief
typedef std::list<Group> SubgroupList;
//! Creates a group within the given Options.
- explicit Group(OptionsImpl *parent) : parent_(parent) {}
+ explicit Group(OptionSectionImpl *parent) : parent_(parent) {}
// From IOptionsContainer
virtual IOptionsContainer &addGroup();
virtual OptionInfo *addOption(const AbstractOption &settings);
//! Containing options object.
- OptionsImpl *parent_;
+ OptionSectionImpl *parent_;
/*! \brief
* List of options, in insertion order.
*
* Pointers in this container point to the objects managed by
* Impl::optionsMap_.
*/
- OptionList options_;
+ OptionList options_;
//! List of groups, in insertion order.
- SubgroupList subgroups_;
+ SubgroupList subgroups_;
};
//! Smart pointer for managing an AbstractOptionStorage object.
typedef std::unique_ptr<AbstractOptionStorage>
AbstractOptionStoragePointer;
- //! Convenience type for list of sections.
- typedef std::vector<Options *> SubSectionList;
//! Convenience typedef for a map that contains all the options.
typedef std::map<std::string, AbstractOptionStoragePointer> OptionMap;
+ //! Smart pointer for managing subsections.
+ typedef std::unique_ptr<OptionSectionImpl> SectionPointer;
+ //! Convenience typedef for a container for subsections.
+ typedef std::vector<SectionPointer> SectionList;
+
+ //! Creates storage for a new section.
+ OptionSectionImpl(const OptionManagerContainer &managers, const char *name)
+ : managers_(managers), info_(this), name_(name), rootGroup_(this)
+ {
+ }
+
+ // From IOptionsContainerWithSections
+ virtual IOptionsContainerWithSections &addSection(const OptionSection §ion);
- //! Sets the name and title.
- OptionsImpl(const char *name, const char *title);
+ // From IOptionsContainer
+ virtual IOptionsContainer &addGroup();
+ virtual OptionInfo *addOption(const AbstractOption &settings);
+
+ //! Returns section info object for this section.
+ OptionSectionInfo &info() { return info_; }
+ //! Returns section info object for this section.
+ const OptionSectionInfo &info() const { return info_; }
/*! \brief
* Finds a subsection by name.
*
* Does not throw.
*/
- Options *findSubSection(const char *name) const;
+ OptionSectionImpl *findSection(const char *name) const;
/*! \brief
* Finds an option by name.
*
* Does not throw.
*/
void startSource();
-
- //! Name for the Options object.
- std::string name_;
/*! \brief
- * Option managers set for this collection.
- *
- * This is non-empty only for the top-level Options object.
+ * Calls AbstractOptionStorage::finish() for all options, including
+ * subsections.
*/
- OptionManagerContainer managers_;
+ void finish(ExceptionInitializer *errors);
+
+ //! Reference to the option managers in the parent Options object.
+ const OptionManagerContainer &managers_;
+ //! Info object for this object.
+ OptionSectionInfo info_;
+ //! Name of this section (empty and unused for the root section).
+ std::string name_;
/*! \brief
* Group that contains all options (and subgroups).
*
* This is used to store the insertion order of options.
*/
- Group rootGroup_;
+ Group rootGroup_;
//! Map from option names to options; owns the option storage objects.
- OptionMap optionMap_;
- /*! \brief
- * List of subsections, in insertion order.
- *
- * This container contains only references to external objects; memory
- * management is performed elsewhere.
- */
- SubSectionList subSections_;
- //! Options object that contains this object as a subsection, or NULL.
- Options *parent_;
+ OptionMap optionMap_;
+ //! List of subsections, in insertion order.
+ SectionList subsections_;
+
+ GMX_DISALLOW_COPY_AND_ASSIGN(OptionSectionImpl);
+};
+
+/*! \internal
+ * \brief
+ * Private implementation class for Options.
+ *
+ * Note that in addition to Options, the OptionsAssigner class also directly
+ * accesses this class.
+ *
+ * \ingroup module_options
+ */
+class OptionsImpl
+{
+ public:
+ OptionsImpl();
+
+ //! Option managers set for this collection.
+ OptionManagerContainer managers_;
+ //! Root section for this collection.
+ OptionSectionImpl rootSection_;
};
} // namespace internal
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2014,2015,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.
#include "gromacs/options/abstractoption.h"
#include "gromacs/options/abstractoptionstorage.h"
+#include "gromacs/options/optionsection.h"
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
{
}
+/********************************************************************
+ * IOptionsContainerWithSections
+ */
+
+IOptionsContainerWithSections::~IOptionsContainerWithSections()
+{
+}
+
/********************************************************************
* OptionsImpl
*/
namespace internal
{
-OptionsImpl::OptionsImpl(const char *name, const char * /*title*/)
- : name_(name != NULL ? name : ""), rootGroup_(this),
- parent_(NULL)
+OptionsImpl::OptionsImpl()
+ : rootSection_(managers_, "")
+{
+}
+
+/********************************************************************
+ * OptionSectionImpl
+ */
+
+IOptionsContainerWithSections &OptionSectionImpl::addSection(const OptionSection §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();
+}
+
+IOptionsContainer &OptionSectionImpl::addGroup()
{
+ return rootGroup_.addGroup();
}
-Options *OptionsImpl::findSubSection(const char *name) const
+OptionInfo *OptionSectionImpl::addOption(const AbstractOption &settings)
{
- SubSectionList::const_iterator i;
- for (i = subSections_.begin(); i != subSections_.end(); ++i)
+ return rootGroup_.addOption(settings);
+}
+
+OptionSectionImpl *OptionSectionImpl::findSection(const char *name) const
+{
+ for (const auto §ion : subsections_)
{
- if ((*i)->name() == name)
+ if (section->name_ == name)
{
- return *i;
+ return section.get();
}
}
- return NULL;
+ return nullptr;
}
-AbstractOptionStorage *OptionsImpl::findOption(const char *name) const
+AbstractOptionStorage *OptionSectionImpl::findOption(const char *name) const
{
OptionMap::const_iterator i = optionMap_.find(name);
if (i == optionMap_.end())
{
- return NULL;
+ return nullptr;
}
return i->second.get();
}
-void OptionsImpl::startSource()
+void OptionSectionImpl::startSource()
{
- OptionMap::const_iterator i;
- for (i = optionMap_.begin(); i != optionMap_.end(); ++i)
+ for (const auto &entry : optionMap_)
{
- AbstractOptionStorage &option = *i->second;
- option.startSource();
+ entry.second->startSource();
}
- SubSectionList::const_iterator j;
- for (j = subSections_.begin(); j != subSections_.end(); ++j)
+ for (const auto §ion : subsections_)
{
- Options §ion = **j;
- section.impl_->startSource();
+ section->startSource();
+ }
+}
+
+void OptionSectionImpl::finish(ExceptionInitializer *errors)
+{
+ for (const auto &entry : optionMap_)
+ {
+ AbstractOptionStorage &option = *entry.second;
+ try
+ {
+ option.finish();
+ }
+ catch (UserInputError &ex)
+ {
+ ex.prependContext("In option " + option.name());
+ errors->addCurrentExceptionAsNested();
+ }
+ }
+ for (const auto §ion : subsections_)
+ {
+ try
+ {
+ section->finish(errors);
+ }
+ catch (const UserInputError &)
+ {
+ errors->addCurrentExceptionAsNested();
+ }
}
}
/********************************************************************
- * OptionsImpl::Group
+ * OptionSectionImpl::Group
*/
-IOptionsContainer &OptionsImpl::Group::addGroup()
+IOptionsContainer &OptionSectionImpl::Group::addGroup()
{
subgroups_.push_back(Group(parent_));
return subgroups_.back();
}
-OptionInfo *OptionsImpl::Group::addOption(const AbstractOption &settings)
+OptionInfo *OptionSectionImpl::Group::addOption(const AbstractOption &settings)
{
- OptionsImpl *root = parent_;
- while (root->parent_ != NULL)
- {
- root = root->parent_->impl_.get();
- }
- AbstractOptionStoragePointer option(settings.createStorage(root->managers_));
+ OptionSectionImpl::AbstractOptionStoragePointer
+ option(settings.createStorage(parent_->managers_));
options_.reserve(options_.size() + 1);
- std::pair<OptionMap::iterator, bool> insertionResult =
+ auto insertionResult =
parent_->optionMap_.insert(std::make_pair(option->name(),
std::move(option)));
if (!insertionResult.second)
{
- GMX_THROW(APIError("Duplicate option: " + option->name()));
+ const std::string &name = insertionResult.first->second->name();
+ GMX_THROW(APIError("Duplicate option: " + name));
}
AbstractOptionStorage &insertedOption = *insertionResult.first->second;
options_.push_back(&insertedOption);
* Options
*/
-Options::Options(const char *name, const char *title)
- : impl_(new OptionsImpl(name, title))
+Options::Options()
+ : impl_(new OptionsImpl)
{
}
{
}
-const std::string &Options::name() const
-{
- return impl_->name_;
-}
-
void Options::addManager(IOptionManager *manager)
{
- GMX_RELEASE_ASSERT(impl_->parent_ == NULL,
- "Can only add a manager in a top-level Options object");
// This ensures that all options see the same set of managers.
- GMX_RELEASE_ASSERT(impl_->optionMap_.empty(),
+ GMX_RELEASE_ASSERT(impl_->rootSection_.optionMap_.empty(),
"Can only add a manager before options");
// This check could be relaxed if we instead checked that the subsections
// do not have options.
- GMX_RELEASE_ASSERT(impl_->subSections_.empty(),
+ GMX_RELEASE_ASSERT(impl_->rootSection_.subsections_.empty(),
"Can only add a manager before subsections");
impl_->managers_.add(manager);
}
-void Options::addSubSection(Options *section)
+IOptionsContainerWithSections &Options::addSection(const OptionSection §ion)
{
- // This is required, because managers are used from the root Options
- // object, so they are only seen after the subsection has been added.
- GMX_RELEASE_ASSERT(section->impl_->optionMap_.empty(),
- "Can only add a subsection before it has any options");
- GMX_RELEASE_ASSERT(section->impl_->managers_.empty(),
- "Can only have managers in a top-level Options object");
- // Make sure that section is not already inserted somewhere.
- GMX_RELEASE_ASSERT(section->impl_->parent_ == NULL,
- "Cannot add as subsection twice");
- // Make sure that there are no duplicate sections.
- GMX_RELEASE_ASSERT(impl_->findSubSection(section->name().c_str()) == NULL,
- "Duplicate subsection name");
- impl_->subSections_.push_back(section);
- section->impl_->parent_ = this;
+ return impl_->rootSection_.addSection(section);
}
IOptionsContainer &Options::addGroup()
{
- return impl_->rootGroup_.addGroup();
+ return impl_->rootSection_.addGroup();
}
OptionInfo *Options::addOption(const AbstractOption &settings)
{
- return impl_->rootGroup_.addOption(settings);
+ return impl_->rootSection_.addOption(settings);
+}
+
+OptionSectionInfo &Options::rootSection()
+{
+ return impl_->rootSection_.info();
+}
+
+const OptionSectionInfo &Options::rootSection() const
+{
+ return impl_->rootSection_.info();
}
void Options::finish()
{
// TODO: Consider how to customize these error messages based on context.
- ExceptionInitializer errors("Invalid input values");
- OptionsImpl::OptionMap::const_iterator i;
- for (i = impl_->optionMap_.begin(); i != impl_->optionMap_.end(); ++i)
- {
- AbstractOptionStorage &option = *i->second;
- try
- {
- option.finish();
- }
- catch (UserInputError &ex)
- {
- ex.prependContext("In option " + option.name());
- errors.addCurrentExceptionAsNested();
- }
- }
- OptionsImpl::SubSectionList::const_iterator j;
- for (j = impl_->subSections_.begin(); j != impl_->subSections_.end(); ++j)
- {
- Options §ion = **j;
- try
- {
- section.finish();
- }
- catch (const UserInputError &)
- {
- errors.addCurrentExceptionAsNested();
- }
- }
+ ExceptionInitializer errors("Invalid input values");
+ impl_->rootSection_.finish(&errors);
if (errors.hasNestedExceptions())
{
// TODO: This exception type may not always be appropriate.
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2014,2015,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.
#include <string>
-#include "gromacs/options/ioptionscontainer.h"
+#include "gromacs/options/ioptionscontainerwithsections.h"
#include "gromacs/utility/classhelpers.h"
namespace gmx
{
class AbstractOption;
+class OptionSection;
+class OptionSectionInfo;
class OptionsAssigner;
-class OptionsIterator;
namespace internal
{
* Collection of options.
*
* See \ref module_options for an overview of how the options work.
- * The IOptionsContainer interface documents how to add options.
+ * The IOptionsContainerWithSections interface documents how to add options.
*
* In order to keep the public interface of this class simple, functionality
* to assign values to options is provided by a separate OptionsAssigner class.
* \inpublicapi
* \ingroup module_options
*/
-class Options : public IOptionsContainer
+class Options : public IOptionsContainerWithSections
{
public:
- /*! \brief
- * Initializes the name and title of an option collection.
- *
- * \param[in] name Single-word name.
- * \param[in] title Descriptive title.
- *
- * Copies the input strings.
- */
- Options(const char *name, const char *title);
+ //! Initializes an empty options root container.
+ Options();
~Options();
- //! Returns the short name of the option collection.
- const std::string &name() const;
-
/*! \brief
* Adds an option manager.
*
* The Options object (and its contained options) only stores a
* reference to the object.
*
- * This method cannot be called after adding options or subsections.
+ * This method cannot be called after adding options or sections.
*/
void addManager(IOptionManager *manager);
- /*! \brief
- * Adds an option collection as a subsection of this collection.
- *
- * \param[in] section Subsection to add.
- *
- * The name() field of \p section is used as the name of the
- * subsection. If an attempt is made to add two different subsections
- * with the same name, this function asserts.
- *
- * \p section should not have any options added at the point this
- * method is called.
- *
- * Only a pointer to the provided object is stored. The caller is
- * responsible that the object exists for the lifetime of the
- * collection.
- * It is not possible to add the same Options object as a subsection to
- * several different Options.
- * If an attempt is made, the function asserts.
- */
- void addSubSection(Options *section);
+ // 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();
+ //! Returns a handle to the root section.
+ const OptionSectionInfo &rootSection() const;
+
/*! \brief
* Notifies the collection that all option values are assigned.
*
private:
PrivateImplPointer<internal::OptionsImpl> impl_;
- //! Needed for the implementation to access subsections.
- friend class internal::OptionsImpl;
//! Needed to be able to extend the interface of this object.
friend class OptionsAssigner;
- //! Needed to be able to extend the interface of this object.
- friend class OptionsIterator;
- //! Needed to be able to extend the interface of this object.
- friend class OptionsModifyingIterator;
};
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015,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.
class OptionsAssigner::Impl
{
public:
+ //! Shorthand for the internal type used to represent a section.
+ typedef internal::OptionSectionImpl Section;
+
//! Sets the option object to assign to.
explicit Impl(Options *options);
//! Returns true if a subsection has been set.
- bool inSubSection() const { return sectionStack_.size() > 1; }
+ bool inSection() const { return sectionStack_.size() > 1; }
//! Returns the Options object for the current section.
- Options ¤tSection() const { return *sectionStack_.back(); }
+ Section ¤tSection() const { return *sectionStack_.back(); }
/*! \brief
* Finds an option by the given name.
*
*
* The first element always points to \a options_.
*/
- std::vector<Options *> sectionStack_;
+ std::vector<Section *> sectionStack_;
//! Current option being assigned to, or NULL if none.
AbstractOptionStorage *currentOption_;
/*! \brief
: options_(*options), bAcceptBooleanNoPrefix_(false),
currentOption_(NULL), currentValueCount_(0), reverseBoolean_(false)
{
- sectionStack_.push_back(&options_);
+ sectionStack_.push_back(&options_.impl_->rootSection_);
}
AbstractOptionStorage *
{
GMX_RELEASE_ASSERT(currentOption_ == NULL,
"Cannot search for another option while processing one");
- const Options §ion = currentSection();
- AbstractOptionStorage *option = section.impl_->findOption(name);
+ const Section §ion = currentSection();
+ AbstractOptionStorage *option = section.findOption(name);
if (option == NULL && bAcceptBooleanNoPrefix_)
{
if (name[0] == 'n' && name[1] == 'o')
{
- option = section.impl_->findOption(name + 2);
+ option = section.findOption(name + 2);
if (option != NULL && option->isBoolean())
{
reverseBoolean_ = true;
void OptionsAssigner::start()
{
- impl_->options_.impl_->startSource();
+ impl_->options_.impl_->rootSection_.startSource();
}
-void OptionsAssigner::startSubSection(const char *name)
+void OptionsAssigner::startSection(const char *name)
{
- Options *section = impl_->currentSection().impl_->findSubSection(name);
+ Impl::Section *section = impl_->currentSection().findSection(name);
if (section == NULL)
{
GMX_THROW(InvalidInputError("Unknown subsection"));
}
}
-void OptionsAssigner::finishSubSection()
+void OptionsAssigner::finishSection()
{
// Should only be called if we are in a subsection.
- GMX_RELEASE_ASSERT(impl_->inSubSection(), "startSubSection() not called");
+ GMX_RELEASE_ASSERT(impl_->inSection(), "startSection() not called");
impl_->sectionStack_.pop_back();
}
void OptionsAssigner::finish()
{
GMX_RELEASE_ASSERT(impl_->currentOption_ == NULL, "finishOption() not called");
- GMX_RELEASE_ASSERT(!impl_->inSubSection(), "finishSubSection() not called");
+ GMX_RELEASE_ASSERT(!impl_->inSection(), "finishSection() not called");
}
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015,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.
assigner.startOption("opt1");
assigner.appendValue("3");
assigner.finishOption();
- assigner.startSubSection("section");
+ assigner.startSection("section");
assigner.startOption("opt2"); // Now in the subsection
assigner.appendValue("yes");
assigner.finishOption();
- assigner.finishSubSection()
+ assigner.finishSection()
assigner.startOption("opt3"); // Again in the main options
assigner.appendValue("2");
assigner.finishOption();
*
* Strong exception safety guarantee.
*/
- void startSubSection(const char *name);
+ void startSection(const char *name);
/*! \brief
* Starts assigning values for an option.
*
*
* Does not throw.
*/
- void finishSubSection();
+ void finishSection();
/*! \brief
* Finish assigning options through the object.
*
--- /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 gmx::OptionSection and gmx::OptionSectionInfo.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \inpublicapi
+ * \ingroup module_options
+ */
+#ifndef GMX_OPTIONS_OPTIONSECTION_H
+#define GMX_OPTIONS_OPTIONSECTION_H
+
+#include "gromacs/utility/classhelpers.h"
+
+namespace gmx
+{
+
+namespace internal
+{
+class OptionSectionImpl;
+}
+
+class OptionSection
+{
+ public:
+ explicit OptionSection(const char *name) : name_(name) {}
+
+ private:
+ const char *name_;
+
+ friend class internal::OptionSectionImpl;
+};
+
+class OptionSectionInfo
+{
+ public:
+ //! Wraps a given section storage object.
+ explicit OptionSectionInfo(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(OptionSectionInfo);
+};
+
+} // namespace gmx
+
+#endif
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2012,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2010,2012,2014,2015,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.
#include "gromacs/options/abstractoptionstorage.h"
#include "gromacs/options/options.h"
+#include "gromacs/options/optionsection.h"
#include "options-impl.h"
//! Helper function to recursively visit all options in a group.
template <class VisitorType>
-void acceptOptionsGroup(const OptionsImpl::Group &group, VisitorType *visitor)
+void acceptOptionsGroup(const internal::OptionSectionImpl::Group &group, VisitorType *visitor)
{
- OptionsImpl::Group::OptionList::const_iterator option;
- for (option = group.options_.begin(); option != group.options_.end(); ++option)
+ for (const auto &option : group.options_)
{
- visitOption(visitor, (*option)->optionInfo());
+ visitOption(visitor, option->optionInfo());
}
- OptionsImpl::Group::SubgroupList::const_iterator subgroup;
- for (subgroup = group.subgroups_.begin(); subgroup != group.subgroups_.end(); ++subgroup)
+ for (const auto &subgroup : group.subgroups_)
{
- acceptOptionsGroup(*subgroup, visitor);
+ acceptOptionsGroup(subgroup, visitor);
}
}
*/
OptionsIterator::OptionsIterator(const Options &options)
- : options_(options)
+ : section_(options.rootSection().section())
{
}
-void OptionsIterator::acceptSubSections(OptionsVisitor *visitor) const
+OptionsIterator::OptionsIterator(const OptionSectionInfo §ion)
+ : section_(section.section())
{
- const OptionsImpl::SubSectionList &subSectionList =
- options_.impl_->subSections_;
- OptionsImpl::SubSectionList::const_iterator i;
- for (i = subSectionList.begin(); i != subSectionList.end(); ++i)
+}
+
+void OptionsIterator::acceptSections(OptionsVisitor *visitor) const
+{
+ for (const auto §ion : section_.subsections_)
{
- visitor->visitSubSection(*(*i));
+ visitor->visitSection(section->info());
}
}
void OptionsIterator::acceptOptions(OptionsVisitor *visitor) const
{
- acceptOptionsGroup(options_.impl_->rootGroup_, visitor);
+ acceptOptionsGroup(section_.rootGroup_, visitor);
}
/********************************************************************
*/
OptionsModifyingIterator::OptionsModifyingIterator(Options *options)
- : options_(*options)
+ : section_(options->rootSection().section())
+{
+}
+
+OptionsModifyingIterator::OptionsModifyingIterator(OptionSectionInfo *section)
+ : section_(section->section())
{
}
-void OptionsModifyingIterator::acceptSubSections(OptionsModifyingVisitor *visitor) const
+void OptionsModifyingIterator::acceptSections(OptionsModifyingVisitor *visitor) const
{
- const OptionsImpl::SubSectionList &subSectionList =
- options_.impl_->subSections_;
- OptionsImpl::SubSectionList::const_iterator i;
- for (i = subSectionList.begin(); i != subSectionList.end(); ++i)
+ for (auto §ion : section_.subsections_)
{
- visitor->visitSubSection(*i);
+ visitor->visitSection(§ion->info());
}
}
void OptionsModifyingIterator::acceptOptions(OptionsModifyingVisitor *visitor) const
{
- acceptOptionsGroup(options_.impl_->rootGroup_, visitor);
+ acceptOptionsGroup(section_.rootGroup_, visitor);
}
} // namespace gmx
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2014,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.
{
class Options;
+class OptionSectionInfo;
+
+namespace internal
+{
+class OptionSectionImpl;
+}
/*! \libinternal \brief
* Pure interface for visiting options in a Options object.
public:
virtual ~OptionsVisitor() {}
- /*! \brief
- * Called for each subsection in Options.
- */
- virtual void visitSubSection(const Options §ion) = 0;
- /*! \brief
- * Called for each option in Options.
- */
+ //! Called for each section.
+ virtual void visitSection(const OptionSectionInfo §ion) = 0;
+ //! Called for each option.
virtual void visitOption(const OptionInfo &option) = 0;
};
public:
virtual ~OptionsTypeVisitor() {}
- virtual void visitSubSection(const Options §ion) = 0;
+ virtual void visitSection(const OptionSectionInfo §ion) = 0;
/*! \brief
* Called for each option of type \p InfoType.
*/
/*! \libinternal \brief
* Decorator class for visiting options in a Options object.
*
- * This class provides an interface for looping through subsections and
+ * This class provides an interface for looping through sections and
* options in a Options object.
*
* Typical use (loop over all options, iteratively descending into
class Visitor : public gmx::OptionsVisitor
{
public:
- void visitSubSection(const Options §ion)
+ void visitSection(const Options §ion)
{
OptionsIterator iterator(section);
- iterator.acceptSubSections(this);
+ iterator.acceptSections(this);
iterator.acceptOptions(this);
}
}
}
- Visitor().visitSubSection(options);
+ Visitor().visitSection(options);
* \endcode
*
* \inlibraryapi
public:
/*! \brief
* Creates an object for visiting options in a Options object.
+ *
+ * The created iterator iterates over the "root" section in the Options
+ * object.
*/
explicit OptionsIterator(const Options &options);
+ //! Creates an object for visiting options in an options section.
+ explicit OptionsIterator(const OptionSectionInfo §ion);
- /*! \brief
- * Visits each subsection in the wrapped Options object.
- */
- void acceptSubSections(OptionsVisitor *visitor) const;
- /*! \brief
- * Visits each option in the wrapped Options object.
- */
+ //! Visits each section in the wrapped section.
+ void acceptSections(OptionsVisitor *visitor) const;
+ //! Visits each option in the wrapped section.
void acceptOptions(OptionsVisitor *visitor) const;
private:
- //! The wrapped Options object.
- const Options &options_;
+ //! The wrapped section object.
+ const internal::OptionSectionImpl §ion_;
GMX_DISALLOW_COPY_AND_ASSIGN(OptionsIterator);
};
public:
virtual ~OptionsModifyingVisitor() {}
- /*! \brief
- * Called for each subsection in Options.
- */
- virtual void visitSubSection(Options *section) = 0;
- /*! \brief
- * Called for each option in Options.
- */
+ //! Called for each section.
+ virtual void visitSection(OptionSectionInfo *section) = 0;
+ //! Called for each option.
virtual void visitOption(OptionInfo *option) = 0;
};
public:
virtual ~OptionsModifyingTypeVisitor() {}
- virtual void visitSubSection(Options *section) = 0;
+ virtual void visitSection(OptionSectionInfo *section) = 0;
/*! \brief
* Called for each option of type \p InfoType.
*/
public:
/*! \brief
* Creates an object for visiting options in a Options object.
+ *
+ * The created iterator iterates over the "root" section in the Options
+ * object.
*/
explicit OptionsModifyingIterator(Options *options);
+ //! Creates an object for visiting options in an options section.
+ explicit OptionsModifyingIterator(OptionSectionInfo *section);
- /*! \brief
- * Visits each subsection in the wrapped Options object.
- */
- void acceptSubSections(OptionsModifyingVisitor *visitor) const;
- /*! \brief
- * Visits each option in the wrapped Options object.
- */
+ //! Visits each section in the wrapped section.
+ void acceptSections(OptionsModifyingVisitor *visitor) const;
+ //! Visits each option in the wrapped section.
void acceptOptions(OptionsModifyingVisitor *visitor) const;
private:
- //! The wrapped Options object.
- Options &options_;
+ //! The wrapped section object.
+ internal::OptionSectionImpl §ion_;
GMX_DISALLOW_COPY_AND_ASSIGN(OptionsModifyingIterator);
};
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,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.
*/
TEST(AbstractOptionStorageTest, HandlesSetInFinish)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::vector<std::string> values;
MockOptionInfo *info = options.addOption(
MockOption("name").required().storeVector(&values));
*/
TEST(AbstractOptionStorageTest, HandlesValueRemoval)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::vector<std::string> values;
MockOptionInfo *info = options.addOption(
MockOption("name").storeVector(&values).multiValue());
*/
TEST(AbstractOptionStorageTest, HandlesValueAddition)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::vector<std::string> values;
MockOptionInfo *info = options.addOption(
MockOption("name").storeVector(&values).multiValue());
*/
TEST(AbstractOptionStorageTest, HandlesTooManyValueAddition)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::vector<std::string> values;
MockOptionInfo *info = options.addOption(
MockOption("name").storeVector(&values).valueCount(2));
*/
TEST(AbstractOptionStorageTest, AllowsEmptyValues)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::vector<std::string> values;
MockOptionInfo *info = options.addOption(
MockOption("name").storeVector(&values).valueCount(0));
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,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.
TEST(FileNameOptionTest, HandlesRequiredDefaultValueWithoutExtension)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::string value;
ASSERT_NO_THROW_GMX(options.addOption(
FileNameOption("f").store(&value).required()
TEST(FileNameOptionTest, HandlesRequiredOptionWithoutValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::string value;
ASSERT_NO_THROW_GMX(options.addOption(
FileNameOption("f").store(&value).required()
TEST(FileNameOptionTest, HandlesOptionalUnsetOption)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::string value;
ASSERT_NO_THROW_GMX(options.addOption(
FileNameOption("f").store(&value)
TEST(FileNameOptionTest, HandlesOptionalDefaultValueWithoutExtension)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::string value;
ASSERT_NO_THROW_GMX(options.addOption(
FileNameOption("f").store(&value)
TEST(FileNameOptionTest, HandlesRequiredCustomDefaultExtension)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::string value;
ASSERT_NO_THROW_GMX(options.addOption(
FileNameOption("f").store(&value).required()
TEST(FileNameOptionTest, HandlesOptionalCustomDefaultExtension)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::string value;
ASSERT_NO_THROW_GMX(options.addOption(
FileNameOption("f").store(&value)
TEST(FileNameOptionTest, GivesErrorOnUnknownFileSuffix)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::string value;
ASSERT_NO_THROW_GMX(options.addOption(
FileNameOption("f").store(&value)
TEST(FileNameOptionTest, GivesErrorOnInvalidFileSuffix)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::string value;
ASSERT_NO_THROW_GMX(options.addOption(
FileNameOption("f").store(&value)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,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.
{
public:
FileNameOptionManagerTest()
- : options_(NULL, NULL)
{
manager_.setInputRedirector(&redirector_);
options_.addManager(&manager_);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015,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.
TEST(OptionsTest, FailsOnNonsafeStorage)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int value = -1;
using gmx::IntegerOption;
ASSERT_THROW_GMX(options.addOption(IntegerOption("name").store(&value)
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015,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.
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/options.h"
+#include "gromacs/options/optionsection.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/stringutil.h"
TEST(OptionsAssignerTest, HandlesMissingRequiredParameter)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int value = 0;
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerTest, HandlesRequiredParameterWithDefaultValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int value = 0;
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerTest, HandlesInvalidMultipleParameter)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::vector<int> values;
bool bIsSet = false;
using gmx::IntegerOption;
TEST(OptionsAssignerTest, HandlesMultipleParameter)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::vector<int> values;
bool bIsSet = false;
using gmx::IntegerOption;
TEST(OptionsAssignerTest, HandlesMissingValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int value1 = 0, value2 = 0;
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value1)));
TEST(OptionsAssignerTest, HandlesExtraValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int value1 = 0;
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value1)));
TEST(OptionsAssignerTest, HandlesGroups)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
gmx::IOptionsContainer &group1 = options.addGroup();
gmx::IOptionsContainer &group2 = options.addGroup();
int value = 3;
EXPECT_EQ(6, value2);
}
-TEST(OptionsAssignerTest, HandlesSubSections)
+TEST(OptionsAssignerTest, HandlesSections)
{
- gmx::Options options(NULL, NULL);
- gmx::Options sub1("section1", NULL);
- gmx::Options sub2("section2", NULL);
+ using gmx::OptionSection;
+ gmx::Options options;
+ auto &sub1 = options.addSection(OptionSection("section1"));
+ auto &sub2 = options.addSection(OptionSection("section2"));
int value = 3;
int value1 = 1;
int value2 = 2;
using gmx::IntegerOption;
- ASSERT_NO_THROW(options.addSubSection(&sub1));
- ASSERT_NO_THROW(options.addSubSection(&sub2));
- ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
- ASSERT_NO_THROW(sub1.addOption(IntegerOption("p").store(&value1)));
- ASSERT_NO_THROW(sub2.addOption(IntegerOption("p").store(&value2)));
+ ASSERT_NO_THROW_GMX(options.addOption(IntegerOption("p").store(&value)));
+ ASSERT_NO_THROW_GMX(sub1.addOption(IntegerOption("p").store(&value1)));
+ ASSERT_NO_THROW_GMX(sub2.addOption(IntegerOption("p").store(&value2)));
gmx::OptionsAssigner assigner(&options);
EXPECT_NO_THROW(assigner.start());
- ASSERT_NO_THROW(assigner.startSubSection("section1"));
+ ASSERT_NO_THROW(assigner.startSection("section1"));
ASSERT_NO_THROW(assigner.startOption("p"));
EXPECT_NO_THROW(assigner.appendValue("5"));
EXPECT_NO_THROW(assigner.finishOption());
- EXPECT_NO_THROW(assigner.finishSubSection());
+ EXPECT_NO_THROW(assigner.finishSection());
ASSERT_NO_THROW(assigner.startOption("p"));
EXPECT_NO_THROW(assigner.appendValue("4"));
EXPECT_NO_THROW(assigner.finishOption());
- ASSERT_NO_THROW(assigner.startSubSection("section2"));
+ ASSERT_NO_THROW(assigner.startSection("section2"));
ASSERT_NO_THROW(assigner.startOption("p"));
EXPECT_NO_THROW(assigner.appendValue("6"));
EXPECT_NO_THROW(assigner.finishOption());
- EXPECT_NO_THROW(assigner.finishSubSection());
+ EXPECT_NO_THROW(assigner.finishSection());
EXPECT_NO_THROW(assigner.finish());
EXPECT_NO_THROW(options.finish());
TEST(OptionsAssignerTest, HandlesMultipleSources)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int value = -1;
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
TEST(OptionsAssignerBooleanTest, StoresYesValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
bool value = false;
using gmx::BooleanOption;
ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
TEST(OptionsAssignerBooleanTest, SetsBooleanWithoutExplicitValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
bool value = false;
using gmx::BooleanOption;
ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
TEST(OptionsAssignerBooleanTest, ClearsBooleanWithPrefixNo)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
bool value = true;
using gmx::BooleanOption;
ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
TEST(OptionsAssignerBooleanTest, HandlesBooleanWithPrefixAndValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
bool value = false;
using gmx::BooleanOption;
ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
TEST(OptionsAssignerIntegerTest, StoresSingleValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int value = 1;
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
TEST(OptionsAssignerIntegerTest, HandlesEmptyValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int value = 1;
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
TEST(OptionsAssignerIntegerTest, HandlesInvalidValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int value = 1;
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
TEST(OptionsAssignerIntegerTest, HandlesOverflow)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int value = 1;
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
TEST(OptionsAssignerIntegerTest, StoresDefaultValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int value = -1;
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerIntegerTest, StoresDefaultValueIfSet)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int value = -1;
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerIntegerTest, HandlesDefaultValueIfSetWhenNotSet)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int value = -1;
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerIntegerTest, HandlesBothDefaultValues)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int value = -1;
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerIntegerTest, StoresToVector)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::vector<int> values;
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerIntegerTest, HandlesVectors)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int vec[3] = {0, 0, 0};
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
TEST(OptionsAssignerIntegerTest, HandlesVectorFromSingleValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int vec[3] = {0, 0, 0};
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int vec[3] = {3, 2, 1};
using gmx::IntegerOption;
ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValueWithInvalidAssignment)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
int vec[3] = {3, 2, 1};
std::vector<int> vec2(vec, vec+3);
using gmx::IntegerOption;
TEST(OptionsAssignerDoubleTest, StoresSingleValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
double value = 0.0;
using gmx::DoubleOption;
ASSERT_NO_THROW(options.addOption(DoubleOption("p").store(&value)));
TEST(OptionsAssignerDoubleTest, HandlesEmptyValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
double value = 1.0;
using gmx::DoubleOption;
ASSERT_NO_THROW(options.addOption(DoubleOption("p").store(&value)));
TEST(OptionsAssignerStringTest, StoresSingleValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::string value;
using gmx::StringOption;
ASSERT_NO_THROW(options.addOption(StringOption("p").store(&value)));
TEST(OptionsAssignerStringTest, HandlesEnumValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::string value;
using gmx::StringOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerStringTest, HandlesEnumValueFromNullTerminatedArray)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::string value;
const char * const allowed[] = { "none", "test", "value", NULL };
using gmx::StringOption;
TEST(OptionsAssignerStringTest, HandlesIncorrectEnumValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::string value;
using gmx::StringOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerStringTest, CompletesEnumValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::string value;
using gmx::StringOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerStringTest, HandlesEnumWithNoValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::string value;
using gmx::StringOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerStringTest, HandlesEnumDefaultValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::string value;
using gmx::StringOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerStringTest, HandlesEnumDefaultValueFromVariable)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::string value("test");
using gmx::StringOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerStringTest, HandlesEnumDefaultValueFromVector)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::vector<std::string> value;
value.push_back("test");
value.push_back("value");
TEST(OptionsAssignerEnumTest, StoresSingleValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
TestEnum value = etestNone;
using gmx::EnumOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerEnumTest, StoresVectorValues)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::vector<TestEnum> values;
using gmx::EnumOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerEnumTest, HandlesInitialValueOutOfRange)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
TestEnum value = etestNR;
using gmx::EnumOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerEnumTest, HandlesEnumDefaultValue)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
TestEnum value = etestNone;
using gmx::EnumOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerEnumTest, HandlesEnumDefaultValueFromVariable)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
TestEnum value = etestTest;
using gmx::EnumOption;
ASSERT_NO_THROW(options.addOption(
TEST(OptionsAssignerEnumTest, HandlesEnumDefaultValueFromVector)
{
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
std::vector<TestEnum> value;
value.push_back(etestNone);
value.push_back(etestTest);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,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.
{
gmx::TimeUnitBehavior behavior;
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
double value = 0.0;
using gmx::DoubleOption;
ASSERT_NO_THROW_GMX(options.addOption(DoubleOption("p").store(&value).timeValue()));
{
gmx::TimeUnitBehavior behavior;
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
double value = 1.5, value2 = 0.0;
using gmx::DoubleOption;
ASSERT_NO_THROW_GMX(options.addOption(DoubleOption("p").store(&value).timeValue()));
{
gmx::TimeUnitBehavior behavior;
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
double value = 0.0;
using gmx::DoubleOption;
ASSERT_NO_THROW_GMX(options.addOption(DoubleOption("p").store(&value).timeValue()));
{
gmx::TimeUnitBehavior behavior;
- gmx::Options options(NULL, NULL);
+ gmx::Options options;
double value = 0.0;
using gmx::DoubleOption;
ASSERT_NO_THROW_GMX(options.addOption(DoubleOption("p").store(&value).timeValue()));
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,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.
//! Initializes a scaler with the given factor.
explicit TimeOptionScaler(double factor) : factor_(factor) {}
- void visitSubSection(Options *section)
+ void visitSection(OptionSectionInfo *section)
{
OptionsModifyingIterator iterator(section);
- iterator.acceptSubSections(this);
+ iterator.acceptSections(this);
iterator.acceptOptions(this);
}
void TimeUnitBehavior::optionsFinishing(Options *options)
{
double factor = TimeUnitManager(timeUnit()).timeScaleFactor();
- TimeOptionScaler<DoubleOptionInfo>(factor).visitSubSection(options);
- TimeOptionScaler<FloatOptionInfo>(factor).visitSubSection(options);
+ TimeOptionScaler<DoubleOptionInfo>(factor).visitSection(&options->rootSection());
+ TimeOptionScaler<FloatOptionInfo>(factor).visitSection(&options->rootSection());
if (timeUnitStore_ != NULL)
{
*timeUnitStore_ = static_cast<TimeUnit>(timeUnit_);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015,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.
};
SelectionOptionTestBase::SelectionOptionTestBase()
- : manager_(&sc_), options_(NULL, NULL)
+ : manager_(&sc_)
{
options_.addManager(&manager_);
sc_.setReferencePosType("atom");
namespace gmx
{
+#ifdef DOXYGEN
/*! \brief
* Macro to declare a class non-copyable and non-assignable.
*
*
* \ingroup module_utility
*/
+#define GMX_DISALLOW_COPY_AND_ASSIGN(ClassName)
+#else
#define GMX_DISALLOW_COPY_AND_ASSIGN(ClassName) \
ClassName &operator=(const ClassName &) = delete; \
ClassName(const ClassName &) = delete
+#endif
/*! \brief
* Macro to declare a class non-assignable.
*
}
bool bHelp = false;
std::string sourceRoot;
- Options options(NULL, NULL);
+ Options options;
// TODO: A single option that accepts multiple names would be nicer.
// Also, we recognize -help, but GTest doesn't, which leads to a bit
// unintuitive behavior.