gmx::Options options(NULL, NULL);
gmx::FileNameOptionManager fileOptManager;
+ options.addManager(&fileOptManager);
options.setDescription(gmx::ConstArrayRef<const char *>(desc, ndesc));
options.addOption(
gmx::IntegerOption("debug").store(&debug_level).hidden()
adapter.pargsToOptions(&options, &pa[i]);
}
- setManagerForFileNameOptions(&options, &fileOptManager);
-
const gmx::CommandLineHelpContext *context =
gmx::GlobalCommandLineHelpContext::get();
if (context != NULL)
using gmx::SelectionFileOption;
using gmx::SelectionOption;
- gmx::Options options(NULL, NULL);
+ gmx::Options options(NULL, NULL);
+ gmx::SelectionCollection selections;
+ gmx::SelectionOptionManager manager(&selections);
+ options.addManager(&manager);
options.addOption(SelectionFileOption("sf"));
options.addOption(SelectionOption("refsel").required()
.description("Reference selection option"));
options.addOption(SelectionOption("sel").required().valueCount(2)
.description("Selection option"));
- gmx::SelectionCollection selections;
- gmx::SelectionOptionManager manager(&selections);
- setManagerForSelectionOptions(&options, &manager);
options.finish();
manager.parseRequestedFromString(
"resname SOL;"
class AbstractOptionStorage;
template <typename T> class OptionStorageTemplate;
+class OptionManagerContainer;
class Options;
//! Smart pointer for managing an AbstractOptionStorage object.
/*! \brief
* Creates a default storage object for the option.
*
- * \returns The created storage object.
- * \throws APIError if invalid option settings have been provided.
+ * \param[in] managers Manager container (unused if the option does
+ * not use a manager).
+ * \returns The created storage object.
+ * \throws APIError if invalid option settings have been provided.
*
* This method is called by Options::addOption() when initializing an
* option from the settings.
*
* Should only be called by Options::addOption().
*/
- virtual AbstractOptionStoragePointer createStorage() const = 0;
+ virtual AbstractOptionStoragePointer createStorage(
+ const OptionManagerContainer &managers) const = 0;
//! Sets the description for the option.
void setDescription(const char *descr) { descr_ = descr; }
* BooleanOption
*/
-AbstractOptionStoragePointer BooleanOption::createStorage() const
+AbstractOptionStoragePointer
+BooleanOption::createStorage(const OptionManagerContainer & /*managers*/) const
{
return AbstractOptionStoragePointer(new BooleanOptionStorage(*this));
}
* IntegerOption
*/
-AbstractOptionStoragePointer IntegerOption::createStorage() const
+AbstractOptionStoragePointer
+IntegerOption::createStorage(const OptionManagerContainer & /*managers*/) const
{
return AbstractOptionStoragePointer(new IntegerOptionStorage(*this));
}
* Int64Option
*/
-AbstractOptionStoragePointer Int64Option::createStorage() const
+AbstractOptionStoragePointer
+Int64Option::createStorage(const OptionManagerContainer & /*managers*/) const
{
return AbstractOptionStoragePointer(new Int64OptionStorage(*this));
}
* DoubleOption
*/
-AbstractOptionStoragePointer DoubleOption::createStorage() const
+AbstractOptionStoragePointer
+DoubleOption::createStorage(const OptionManagerContainer & /*managers*/) const
{
return AbstractOptionStoragePointer(new DoubleOptionStorage(*this));
}
* FloatOption
*/
-AbstractOptionStoragePointer FloatOption::createStorage() const
+AbstractOptionStoragePointer
+FloatOption::createStorage(const OptionManagerContainer & /*managers*/) const
{
return AbstractOptionStoragePointer(new FloatOptionStorage(*this));
}
* StringOption
*/
-AbstractOptionStoragePointer StringOption::createStorage() const
+AbstractOptionStoragePointer
+StringOption::createStorage(const OptionManagerContainer & /*managers*/) const
{
return AbstractOptionStoragePointer(new StringOptionStorage(*this));
}
private:
//! Creates a BooleanOptionStorage object.
- virtual AbstractOptionStoragePointer createStorage() const;
+ virtual AbstractOptionStoragePointer createStorage(
+ const OptionManagerContainer &managers) const;
};
/*! \brief
private:
//! Creates an IntegerOptionStorage object.
- virtual AbstractOptionStoragePointer createStorage() const;
+ virtual AbstractOptionStoragePointer createStorage(
+ const OptionManagerContainer &managers) const;
/*! \brief
* Needed to initialize IntegerOptionStorage from this class without
private:
//! Creates an Int64OptionStorage object.
- virtual AbstractOptionStoragePointer createStorage() const;
+ virtual AbstractOptionStoragePointer createStorage(
+ const OptionManagerContainer &managers) const;
/*! \brief
* Needed to initialize Int64OptionStorage from this class without
private:
//! Creates a DoubleOptionStorage object.
- virtual AbstractOptionStoragePointer createStorage() const;
+ virtual AbstractOptionStoragePointer createStorage(
+ const OptionManagerContainer &managers) const;
bool bTime_;
private:
//! Creates a FloatOptionStorage object.
- virtual AbstractOptionStoragePointer createStorage() const;
+ virtual AbstractOptionStoragePointer createStorage(
+ const OptionManagerContainer &managers) const;
bool bTime_;
private:
//! Creates a StringOptionStorage object.
- virtual AbstractOptionStoragePointer createStorage() const;
+ virtual AbstractOptionStoragePointer createStorage(
+ const OptionManagerContainer &managers) const;
const char *const *enumValues_;
int enumValuesCount_;
#include "gromacs/fileio/filenm.h"
#include "gromacs/options/filenameoptionmanager.h"
+#include "gromacs/options/optionmanagercontainer.h"
#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/file.h"
#include "gromacs/utility/gmxassert.h"
* FileNameOptionStorage
*/
-FileNameOptionStorage::FileNameOptionStorage(const FileNameOption &settings)
- : MyBase(settings), info_(this), manager_(NULL),
+FileNameOptionStorage::FileNameOptionStorage(const FileNameOption &settings,
+ FileNameOptionManager *manager)
+ : MyBase(settings), info_(this), manager_(manager),
filetype_(settings.filetype_), legacyType_(settings.legacyType_),
bRead_(settings.bRead_), bWrite_(settings.bWrite_),
bLibrary_(settings.bLibrary_)
}
}
-void FileNameOptionStorage::setManager(FileNameOptionManager *manager)
-{
- GMX_RELEASE_ASSERT(manager_ == NULL || manager_ == manager,
- "Manager cannot be changed once set");
- if (manager_ == NULL)
- {
- manager_ = manager;
- }
-}
-
std::string FileNameOptionStorage::typeString() const
{
const FileTypeRegistry ®istry = FileTypeRegistry::instance();
{
}
-FileNameOptionStorage &FileNameOptionInfo::option()
-{
- return static_cast<FileNameOptionStorage &>(OptionInfo::option());
-}
-
const FileNameOptionStorage &FileNameOptionInfo::option() const
{
return static_cast<const FileNameOptionStorage &>(OptionInfo::option());
}
-void FileNameOptionInfo::setManager(FileNameOptionManager *manager)
-{
- option().setManager(manager);
-}
-
bool FileNameOptionInfo::isInputFile() const
{
return option().isInputFile();
* FileNameOption
*/
-AbstractOptionStoragePointer FileNameOption::createStorage() const
+AbstractOptionStoragePointer
+FileNameOption::createStorage(const OptionManagerContainer &managers) const
{
- return AbstractOptionStoragePointer(new FileNameOptionStorage(*this));
+ return AbstractOptionStoragePointer(
+ new FileNameOptionStorage(*this, managers.get<FileNameOptionManager>()));
}
} // namespace gmx
using MyBase::defaultValueIfSet;
//! Creates a FileNameOptionStorage object.
- virtual AbstractOptionStoragePointer createStorage() const;
+ virtual AbstractOptionStoragePointer createStorage(
+ const OptionManagerContainer &managers) const;
OptionFileType filetype_;
int legacyType_;
//! Creates an option info object for the given option.
explicit FileNameOptionInfo(FileNameOptionStorage *option);
- /*! \brief
- * Set manager for handling interaction with other options.
- *
- * \param manager File name option manager to set.
- *
- * This must be called before the values are added.
- *
- * Typically it is called through setManagerForFileNameOptions(),
- * which recursively sets the manager for all file name options in
- * an Options object.
- *
- * Does not throw.
- */
- void setManager(FileNameOptionManager *manager);
-
//! Whether the option specifies an input file.
bool isInputFile() const;
//! Whether the option specifies an output file.
ExtensionList extensions() const;
private:
- FileNameOptionStorage &option();
const FileNameOptionStorage &option() const;
};
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/filenameoption.h"
#include "gromacs/options/options.h"
-#include "gromacs/options/optionsvisitor.h"
namespace gmx
{
return impl_->defaultFileName_;
}
-/********************************************************************
- * Global functions
- */
-
-namespace
-{
-
-/*! \internal \brief
- * Visitor that sets the manager for each file name option.
- *
- * \ingroup module_options
- */
-class FileNameOptionManagerSetter : public OptionsModifyingVisitor
-{
- public:
- //! Construct a visitor that sets given manager.
- explicit FileNameOptionManagerSetter(FileNameOptionManager *manager)
- : manager_(manager)
- {
- }
-
- void visitSubSection(Options *section)
- {
- OptionsModifyingIterator iterator(section);
- iterator.acceptSubSections(this);
- iterator.acceptOptions(this);
- }
-
- void visitOption(OptionInfo *option)
- {
- FileNameOptionInfo *fileOption
- = option->toType<FileNameOptionInfo>();
- if (fileOption != NULL)
- {
- fileOption->setManager(manager_);
- }
- }
-
- private:
- FileNameOptionManager *manager_;
-};
-
-} // namespace
-
-void setManagerForFileNameOptions(Options *options,
- FileNameOptionManager *manager)
-{
- FileNameOptionManagerSetter(manager).visitSubSection(options);
-}
-
} // namespace gmx
#include <string>
+#include "options.h"
+
#include "../utility/common.h"
namespace gmx
* most of the non-trivial file name completion logic in this class, so that
* the customizations would be centralized here.
*
- * Creating a FileNameOptionManager for an Options object is optional, even if
+ * Adding a FileNameOptionManager for an Options object is optional, even if
* the Options contains FileNameOption options. Features from the manager are
* not available if the manager is not created, but otherwise the options work.
*
- * \see setManagerForFileNameOptions()
+ * \see Options::addManager()
*
* \inpublicapi
* \ingroup module_selection
*/
-class FileNameOptionManager
+class FileNameOptionManager : public OptionManagerInterface
{
public:
FileNameOptionManager();
- ~FileNameOptionManager();
+ virtual ~FileNameOptionManager();
/*! \brief
* Adds an option for setting the default global file name.
PrivateImplPointer<Impl> impl_;
};
-/*! \brief
- * Set manager for all file name options.
- *
- * Recursively sets the manager to \p manager for all file name options in
- * \p options.
- * Must be called before value assignment starts for \p options.
- *
- * Does not throw.
- *
- * \inpublicapi
- */
-void setManagerForFileNameOptions(Options *options,
- FileNameOptionManager *manager);
-
} // namespace gmx
#endif
class FileNameOptionStorage : public OptionStorageTemplate<std::string>
{
public:
- //! \copydoc StringOptionStorage::StringOptionStorage()
- explicit FileNameOptionStorage(const FileNameOption &settings);
+ /*! \brief
+ * Initializes the storage from option settings.
+ *
+ * \param[in] settings Storage settings.
+ * \param manager Manager for this object (can be NULL).
+ */
+ FileNameOptionStorage(const FileNameOption &settings,
+ FileNameOptionManager *manager);
virtual OptionInfo &optionInfo() { return info_; }
virtual std::string typeString() const;
virtual std::string formatExtraDescription() const;
virtual std::string formatSingleValue(const std::string &value) const;
- //! \copydoc FileNameOptionInfo::setManager()
- void setManager(FileNameOptionManager *manager);
-
//! \copydoc FileNameOptionInfo::isInputFile()
bool isInputFile() const { return bRead_ && !bWrite_; }
//! \copydoc FileNameOptionInfo::isOutputFile()
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2014, 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.
+ */
+/*! \libinternal \file
+ * \brief
+ * Declares gmx::OptionManagerContainer.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_options
+ */
+#ifndef GMX_OPTIONS_OPTIONMANAGERCONTAINER_H
+#define GMX_OPTIONS_OPTIONMANAGERCONTAINER_H
+
+#include <vector>
+
+#include "gromacs/utility/common.h"
+#include "gromacs/utility/gmxassert.h"
+
+namespace gmx
+{
+
+class OptionManagerInterface;
+
+/*! \libinternal
+ * \brief
+ * Container to keep managers added with Options::addManager() and pass them
+ * to options.
+ *
+ * Consistency of the managers (e.g., that there is at most one manager of a
+ * certain type) is only checked when the managers are accessed.
+ *
+ * \inlibraryapi
+ * \ingroup module_options
+ */
+class OptionManagerContainer
+{
+ public:
+ OptionManagerContainer()
+ {
+ }
+
+ //! Returns `true` if there are no managers.
+ bool empty() const { return list_.empty(); }
+
+ //! Adds a manager to the container.
+ void add(OptionManagerInterface *manager)
+ {
+ list_.push_back(manager);
+ }
+ /*! \brief
+ * Retrieves a manager of a certain type.
+ *
+ * \tparam ManagerType Type of manager to retrieve
+ * (should derive from OptionManagerInterface).
+ * \returns The manager, or `NULL` if there is none.
+ *
+ * This method is used in AbstractOption::createStorage() to retrieve
+ * a manager of a certain type for options that use a manager.
+ *
+ * The return value is `NULL` if there is no manager of the given type.
+ * The caller needs to handle this (either by asserting, or by handling
+ * the manager as optional).
+ */
+ template <class ManagerType>
+ ManagerType *get() const
+ {
+ ManagerType *result = NULL;
+ for (ListType::const_iterator i = list_.begin(); i != list_.end(); ++i)
+ {
+ ManagerType *curr = dynamic_cast<ManagerType *>(*i);
+ if (curr != NULL)
+ {
+ GMX_RELEASE_ASSERT(result == NULL,
+ "More than one applicable option manager is set");
+ result = curr;
+ }
+ }
+ return result;
+ }
+
+ private:
+ //! Shorthand for the internal container type.
+ typedef std::vector<OptionManagerInterface *> ListType;
+
+ ListType list_;
+
+ GMX_DISALLOW_COPY_AND_ASSIGN(OptionManagerContainer);
+};
+
+} // namespace gmx
+
+#endif
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014, 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 "abstractoption.h"
+#include "optionmanagercontainer.h"
#include "options.h"
namespace gmx
std::string title_;
//! Full description for the Options object.
std::string description_;
+ /*! \brief
+ * Option managers set for this collection.
+ *
+ * This is non-empty only for the top-level Options object.
+ */
+ OptionManagerContainer managers_;
/*! \brief
* List of subsections, in insertion order.
*
namespace gmx
{
+/********************************************************************
+ * OptionManagerInterface
+ */
+
+OptionManagerInterface::~OptionManagerInterface()
+{
+}
+
/********************************************************************
* Options::Impl
*/
impl_->description_ = concatenateStrings(descArray.data(), descArray.size());
}
+void Options::addManager(OptionManagerInterface *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_->options_.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(),
+ "Can only add a manager before subsections");
+ impl_->managers_.add(manager);
+}
+
void Options::addSubSection(Options *section)
{
+ // 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_->options_.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");
OptionInfo *Options::addOption(const AbstractOption &settings)
{
- AbstractOptionStoragePointer option(settings.createStorage());
+ Options::Impl *root = impl_.get();
+ while (root->parent_ != NULL)
+ {
+ root = root->parent_->impl_.get();
+ }
+ AbstractOptionStoragePointer option(settings.createStorage(root->managers_));
if (impl_->findOption(option->name().c_str()) != NULL)
{
GMX_THROW(APIError("Duplicate option: " + option->name()));
class OptionsAssigner;
class OptionsIterator;
+/*! \brief
+ * Base class for option managers.
+ *
+ * This class is used as a marker for all classes that are used with
+ * Options::addManager(). It doesn't provide any methods, but only supports
+ * transporting these classes through the Options collection into the
+ * individual option implementation classes.
+ *
+ * The virtual destructor is present to make this class polymorphic, such that
+ * `dynamic_cast` can be used when retrieving a manager of a certain type for
+ * the individual options.
+ *
+ * \inlibraryapi
+ * \ingroup module_options
+ */
+class OptionManagerInterface
+{
+ protected:
+ virtual ~OptionManagerInterface();
+};
+
/*! \brief
* Collection of options.
*
*/
void setDescription(const ConstArrayRef<const char *> &descArray);
+ /*! \brief
+ * Adds an option manager.
+ *
+ * \param manager Manager to add.
+ * \throws std::bad_alloc if out of memory.
+ *
+ * Option managers are used by some types of options that require
+ * interaction between different option instances (e.g., selection
+ * options), or need to support globally set properties (e.g., a global
+ * default file prefix). Option objects can retrieve the pointer to
+ * their manager when they are created, and the caller can alter the
+ * behavior of the options through the manager.
+ * See the individual managers for details.
+ *
+ * Caller is responsible for memory management of \p 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.
+ */
+ void addManager(OptionManagerInterface *manager);
+
/*! \brief
* Adds an option collection as a subsection of this collection.
*
* subsection. If an attempt is made to add two different subsections
* with the same name, this function asserts.
*
- * For certain functionality to work properly, no options should
- * be added to the subsection after it has been added to another
- * collection.
+ * \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
}
private:
- virtual gmx::AbstractOptionStoragePointer createStorage() const
+ virtual gmx::AbstractOptionStoragePointer createStorage(
+ const gmx::OptionManagerContainer & /*managers*/) const
{
return gmx::AbstractOptionStoragePointer(new MockOptionStorage(*this));
}
gmx::FileNameOptionManager manager;
gmx::Options options(NULL, NULL);
std::string value;
+ ASSERT_NO_THROW_GMX(options.addManager(&manager));
ASSERT_NO_THROW_GMX(options.addOption(
FileNameOption("f").store(&value).required()
.filetype(gmx::eftTrajectory).inputFile()
.defaultBasename("foo")));
ASSERT_NO_THROW_GMX(manager.addDefaultFileNameOption(&options, "deffnm"));
- ASSERT_NO_THROW_GMX(setManagerForFileNameOptions(&options, &manager));
EXPECT_EQ("foo.xtc", value);
gmx::OptionsAssigner assigner(&options);
gmx::FileNameOptionManager manager;
gmx::Options options(NULL, NULL);
std::string value;
+ ASSERT_NO_THROW_GMX(options.addManager(&manager));
ASSERT_NO_THROW_GMX(options.addOption(
FileNameOption("f").store(&value)
.filetype(gmx::eftTrajectory).inputFile()
.defaultBasename("foo")));
ASSERT_NO_THROW_GMX(manager.addDefaultFileNameOption(&options, "deffnm"));
- ASSERT_NO_THROW_GMX(setManagerForFileNameOptions(&options, &manager));
gmx::OptionsAssigner assigner(&options);
EXPECT_NO_THROW_GMX(assigner.start());
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2010,2011,2012,2013, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014, 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.
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(options.addSubSection(&sub1));
- ASSERT_NO_THROW(options.addSubSection(&sub2));
gmx::OptionsAssigner assigner(&options);
EXPECT_NO_THROW(assigner.start());
int pvalue2 = 2;
int rvalue = 5;
using gmx::IntegerOption;
+ ASSERT_NO_THROW(options.addSubSection(&sub1));
+ ASSERT_NO_THROW(options.addSubSection(&sub2));
ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&pvalue)));
ASSERT_NO_THROW(sub1.addOption(IntegerOption("p").store(&pvalue1)));
ASSERT_NO_THROW(sub1.addOption(IntegerOption("q").store(&qvalue)));
ASSERT_NO_THROW(sub2.addOption(IntegerOption("p").store(&pvalue2)));
ASSERT_NO_THROW(sub2.addOption(IntegerOption("r").store(&rvalue)));
- ASSERT_NO_THROW(options.addSubSection(&sub1));
- ASSERT_NO_THROW(options.addSubSection(&sub2));
gmx::OptionsAssigner assigner(&options);
assigner.setNoStrictSectioning(true);
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014, 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.
explicit SelectionFileOption(const char *name);
private:
- virtual AbstractOptionStoragePointer createStorage() const;
+ virtual AbstractOptionStoragePointer createStorage(
+ const OptionManagerContainer &managers) const;
};
/*! \libinternal \brief
* Does not throw.
*/
explicit SelectionFileOptionInfo(SelectionFileOptionStorage *option);
-
- //! \copydoc SelectionOptionInfo::setManager()
- void setManager(SelectionOptionManager *manager);
-
- private:
- SelectionFileOptionStorage &option();
- const SelectionFileOptionStorage &option() const;
};
} // namespace gmx
* Initializes the storage from option settings.
*
* \param[in] settings Storage settings.
+ * \param manager Manager for this object.
*/
- SelectionFileOptionStorage(const SelectionFileOption &settings);
+ SelectionFileOptionStorage(const SelectionFileOption &settings,
+ SelectionOptionManager *manager);
virtual OptionInfo &optionInfo() { return info_; }
virtual std::string typeString() const { return "file"; }
virtual int valueCount() const { return 0; }
virtual std::string formatValue(int /*i*/) const { return ""; }
- //! \copydoc SelectionFileOptionInfo::setManager()
- void setManager(SelectionOptionManager *manager)
- {
- manager_ = manager;
- }
-
private:
virtual void clearSet();
virtual void convertValue(const std::string &value);
virtual void processSet();
virtual void processAll() {}
- SelectionFileOptionInfo info_;
- SelectionOptionManager *manager_;
- bool bValueParsed_;
+ SelectionFileOptionInfo info_;
+ SelectionOptionManager &manager_;
+ bool bValueParsed_;
};
} // namespace gmx
#include <string>
+#include "gromacs/options/optionmanagercontainer.h"
#include "gromacs/selection/selection.h"
#include "gromacs/selection/selectionoptionmanager.h"
#include "gromacs/utility/exceptions.h"
* SelectionOptionStorage
*/
-SelectionOptionStorage::SelectionOptionStorage(const SelectionOption &settings)
+SelectionOptionStorage::SelectionOptionStorage(const SelectionOption &settings,
+ SelectionOptionManager *manager)
: MyBase(settings, OptionFlags() | efOption_NoDefaultValue
| efOption_DontCheckMinimumCount),
- info_(this), manager_(NULL), defaultText_(settings.defaultText_),
+ info_(this), manager_(*manager), defaultText_(settings.defaultText_),
selectionFlags_(settings.selectionFlags_)
{
+ GMX_RELEASE_ASSERT(manager != NULL,
+ "SelectionOptionManager must be added before SelectionOption");
GMX_RELEASE_ASSERT(!hasFlag(efOption_MultipleTimes),
"allowMultiple() is not supported for selection options");
-}
-
-
-void SelectionOptionStorage::setManager(SelectionOptionManager *manager)
-{
- GMX_RELEASE_ASSERT(manager_ == NULL || manager_ == manager,
- "Manager cannot be changed once set");
- if (manager_ == NULL)
- {
- manager->registerOption(this);
- manager_ = manager;
- }
+ manager_.registerOption(this);
}
void SelectionOptionStorage::convertValue(const std::string &value)
{
- GMX_RELEASE_ASSERT(manager_ != NULL, "Manager is not set");
-
- manager_->convertOptionValue(this, value, false);
+ manager_.convertOptionValue(this, value, false);
}
void SelectionOptionStorage::processSetValues(ValueList *values)
{
- GMX_RELEASE_ASSERT(manager_ != NULL, "Manager is not set");
-
if (values->size() == 0)
{
- manager_->requestOptionDelayedParsing(this);
+ manager_.requestOptionDelayedParsing(this);
}
else if (values->size() < static_cast<size_t>(minValueCount()))
{
void SelectionOptionStorage::processAll()
{
- GMX_RELEASE_ASSERT(manager_ != NULL, "Manager is not set");
if (!isSet() && !defaultText_.empty())
{
- manager_->convertOptionValue(this, defaultText_, true);
+ manager_.convertOptionValue(this, defaultText_, true);
}
if (isRequired() && !isSet())
{
- manager_->requestOptionDelayedParsing(this);
+ manager_.requestOptionDelayedParsing(this);
markAsSet();
}
}
return static_cast<const SelectionOptionStorage &>(OptionInfo::option());
}
-void SelectionOptionInfo::setManager(SelectionOptionManager *manager)
-{
- option().setManager(manager);
-}
-
void SelectionOptionInfo::setValueCount(int count)
{
option().setAllowedValueCount(count);
* SelectionOption
*/
-AbstractOptionStoragePointer SelectionOption::createStorage() const
+AbstractOptionStoragePointer
+SelectionOption::createStorage(const OptionManagerContainer &managers) const
{
- return AbstractOptionStoragePointer(new SelectionOptionStorage(*this));
+ return AbstractOptionStoragePointer(
+ new SelectionOptionStorage(
+ *this, managers.get<SelectionOptionManager>()));
}
* SelectionFileOptionStorage
*/
-SelectionFileOptionStorage::SelectionFileOptionStorage(const SelectionFileOption &settings)
+SelectionFileOptionStorage::SelectionFileOptionStorage(
+ const SelectionFileOption &settings, SelectionOptionManager *manager)
: AbstractOptionStorage(settings, OptionFlags() | efOption_MultipleTimes
| efOption_DontCheckMinimumCount),
- info_(this), manager_(NULL), bValueParsed_(false)
+ info_(this), manager_(*manager), bValueParsed_(false)
{
+ GMX_RELEASE_ASSERT(manager != NULL,
+ "SelectionOptionManager must be added before SelectionFileOption");
}
void SelectionFileOptionStorage::clearSet()
void SelectionFileOptionStorage::convertValue(const std::string &value)
{
- GMX_RELEASE_ASSERT(manager_ != NULL, "Manager is not set");
-
if (bValueParsed_)
{
GMX_THROW(InvalidInputError("More than one file name provided"));
}
bValueParsed_ = true;
// TODO: Should we throw an InvalidInputError if the file does not exist?
- manager_->parseRequestedFromFile(value);
+ manager_.parseRequestedFromFile(value);
}
void SelectionFileOptionStorage::processSet()
{
}
-SelectionFileOptionStorage &SelectionFileOptionInfo::option()
-{
- return static_cast<SelectionFileOptionStorage &>(OptionInfo::option());
-}
-
-const SelectionFileOptionStorage &SelectionFileOptionInfo::option() const
-{
- return static_cast<const SelectionFileOptionStorage &>(OptionInfo::option());
-}
-
-void SelectionFileOptionInfo::setManager(SelectionOptionManager *manager)
-{
- option().setManager(manager);
-}
-
/********************************************************************
* SelectionFileOption
setDescription("Provide selections from files");
}
-AbstractOptionStoragePointer SelectionFileOption::createStorage() const
+AbstractOptionStoragePointer
+SelectionFileOption::createStorage(const OptionManagerContainer &managers) const
{
- return AbstractOptionStoragePointer(new SelectionFileOptionStorage(*this));
+ return AbstractOptionStoragePointer(
+ new SelectionFileOptionStorage(
+ *this, managers.get<SelectionOptionManager>()));
}
} // namespace gmx
*
* Public methods in this class do not throw.
*
+ * To use options of this type, SelectionOptionManager must first be added to
+ * the Options collection. For trajectory analysis tools, the framework takes
+ * care of this.
+ *
* \todo
* Support for specifying that an option accepts, e.g., two to four selections.
* Currently, only a fixed count or any number of selections is possible.
using MyBase::defaultValue;
using MyBase::defaultValueIfSet;
- virtual AbstractOptionStoragePointer createStorage() const;
+ virtual AbstractOptionStoragePointer createStorage(
+ const OptionManagerContainer &managers) const;
const char *defaultText_;
SelectionFlags selectionFlags_;
*/
explicit SelectionOptionInfo(SelectionOptionStorage *option);
- /*! \brief
- * Set manager for handling interaction with other options and the
- * selection collection.
- *
- * \param manager Selection manager to set.
- *
- * This must be called before the values are added.
- *
- * Typically it is called through setManagerForSelectionOptions(),
- * which recursively sets the manager for all selection options in
- * an Options object.
- *
- * Does not throw.
- */
- void setManager(SelectionOptionManager *manager);
-
/*! \brief
* Sets the number of selections allowed for the option.
*
#include <cstdio>
-#include "gromacs/options/optionsvisitor.h"
#include "gromacs/selection/selection.h"
#include "gromacs/selection/selectioncollection.h"
#include "gromacs/selection/selectionoption.h"
impl_->placeSelectionsInRequests(selections);
}
-/********************************************************************
- * Global functions
- */
-
-namespace
-{
-
-/*! \internal \brief
- * Visitor that sets the manager for each selection option.
- *
- * \ingroup module_selection
- */
-class SelectionOptionManagerSetter : public OptionsModifyingVisitor
-{
- public:
- //! Construct a visitor that sets given manager.
- explicit SelectionOptionManagerSetter(SelectionOptionManager *manager)
- : manager_(manager)
- {
- }
-
- void visitSubSection(Options *section)
- {
- OptionsModifyingIterator iterator(section);
- iterator.acceptSubSections(this);
- iterator.acceptOptions(this);
- }
-
- void visitOption(OptionInfo *option)
- {
- SelectionOptionInfo *selOption
- = option->toType<SelectionOptionInfo>();
- if (selOption != NULL)
- {
- selOption->setManager(manager_);
- }
- SelectionFileOptionInfo *selFileOption
- = option->toType<SelectionFileOptionInfo>();
- if (selFileOption != NULL)
- {
- selFileOption->setManager(manager_);
- }
- }
-
- private:
- SelectionOptionManager *manager_;
-};
-
-} // namespace
-
-void setManagerForSelectionOptions(Options *options,
- SelectionOptionManager *manager)
-{
- SelectionOptionManagerSetter(manager).visitSubSection(options);
-}
-
} // namespace gmx
#include <string>
+#include "../options/options.h"
#include "../utility/common.h"
namespace gmx
* require actions outside options parsing.
* It also implements the coupling between SelectionOption and
* SelectionFileOption.
+ * It needs to be added using Options::addManager() before SelectionOption or
+ * SelectionFileOption options can be added to an Options collection.
*
* The main features of this class are:
* - convertOptionValue(), which is used to convert string values into
* parseRequestedFromStdin(), parseRequestedFromFile() or
* parseRequstedFromString().
*
- * \see setManagerForSelectionOptions()
- *
* \inpublicapi
* \ingroup module_selection
*/
-class SelectionOptionManager
+class SelectionOptionManager : public OptionManagerInterface
{
public:
/*! \brief
* \throws std::bad_alloc if out of memory.
*/
explicit SelectionOptionManager(SelectionCollection *selections);
- ~SelectionOptionManager();
+ virtual ~SelectionOptionManager();
/*! \brief
* Adds a selection option to be managed.
friend class SelectionOptionStorage;
};
-/*! \brief
- * Set manager for all selection options.
- *
- * Recursively sets the manager to \p manager for all selection options in
- * \p options.
- * Must be called before value assignment starts for \p options.
- *
- * Does not throw.
- *
- * \inpublicapi
- */
-void setManagerForSelectionOptions(Options *options,
- SelectionOptionManager *manager);
-
} // namespace gmx
#endif
* Initializes the storage from option settings.
*
* \param[in] settings Storage settings.
+ * \param manager Manager for this object.
*/
- SelectionOptionStorage(const SelectionOption &settings);
+ SelectionOptionStorage(const SelectionOption &settings,
+ SelectionOptionManager *manager);
virtual OptionInfo &optionInfo() { return info_; }
virtual std::string typeString() const { return "selection"; }
virtual std::string formatSingleValue(const Selection &value) const;
- //! \copydoc SelectionOptionInfo::setManager()
- void setManager(SelectionOptionManager *manager);
-
/*! \brief
* Adds selections to the storage.
*
virtual void processAll();
SelectionOptionInfo info_;
- SelectionOptionManager *manager_;
+ SelectionOptionManager &manager_;
std::string defaultText_;
SelectionFlags selectionFlags_;
};
public:
SelectionOptionTestBase();
- void setManager();
void loadTopology(const char *filename);
gmx::SelectionCollection sc_;
SelectionOptionTestBase::SelectionOptionTestBase()
: manager_(&sc_), options_(NULL, NULL)
{
+ options_.addManager(&manager_);
sc_.setReferencePosType("atom");
sc_.setOutputPosType("atom");
}
-void SelectionOptionTestBase::setManager()
-{
- setManagerForSelectionOptions(&options_, &manager_);
-}
-
void SelectionOptionTestBase::loadTopology(const char *filename)
{
topManager_.loadTopology(filename);
gmx::Selection sel;
using gmx::SelectionOption;
ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel)));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
using gmx::SelectionOption;
ASSERT_NO_THROW_GMX(options_.addOption(
SelectionOption("sel").store(&sel).onlyStatic()));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
using gmx::SelectionOption;
ASSERT_NO_THROW_GMX(options_.addOption(
SelectionOption("sel").store(&sel).onlyAtoms()));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
using gmx::SelectionOption;
ASSERT_NO_THROW_GMX(options_.addOption(
SelectionOption("sel").store(&sel)));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
using gmx::SelectionOption;
ASSERT_NO_THROW_GMX(options_.addOption(
SelectionOption("sel").store(&sel)));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
gmx::Selection sel;
using gmx::SelectionOption;
ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel)));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
using gmx::SelectionOption;
ASSERT_NO_THROW_GMX(options_.addOption(
SelectionOption("sel").store(sel).valueCount(2)));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
using gmx::SelectionOption;
options_.addOption(SelectionOption("sel").store(&sel)
.defaultSelectionText("all"));
- setManager();
EXPECT_NO_THROW_GMX(options_.finish());
using gmx::SelectionOption;
gmx::SelectionOptionInfo *info = options_.addOption(
SelectionOption("sel").storeVector(&sel).multiValue());
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
using gmx::SelectionOption;
gmx::SelectionOptionInfo *info = options_.addOption(
SelectionOption("sel").store(&sel));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
using gmx::SelectionOption;
gmx::SelectionOptionInfo *info = options_.addOption(
SelectionOption("sel").storeVector(&sel).multiValue());
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
using gmx::SelectionOption;
gmx::SelectionOptionInfo *info = options_.addOption(
SelectionOption("sel").storeVector(&sel).multiValue());
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
using gmx::SelectionOption;
ASSERT_NO_THROW_GMX(options_.addOption(
SelectionOption("sel").store(&sel).required()));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
ASSERT_NO_THROW_GMX(options_.addOption(
SelectionOption("sel").store(sel).required()
.valueCount(2)));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
gmx::Selection sel;
using gmx::SelectionOption;
ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel)));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
using gmx::SelectionOption;
gmx::SelectionOptionInfo *info = options_.addOption(
SelectionOption("sel").storeVector(&sel).valueCount(3));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
ASSERT_NO_THROW_GMX(options_.addOption(
SelectionOption("reqsel").storeVector(&reqsel)
.multiValue().required()));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
SelectionOption("sel1").storeVector(&sel1).multiValue()));
ASSERT_NO_THROW_GMX(options_.addOption(
SelectionOption("sel2").storeVector(&sel2).multiValue()));
- setManager();
gmx::OptionsAssigner assigner(&options_);
std::string value(TestFileManager::getInputFilePath("selfile.dat"));
SelectionOption("sel1").storeVector(&sel1)));
ASSERT_NO_THROW_GMX(options_.addOption(
SelectionOption("sel2").storeVector(&sel2)));
- setManager();
gmx::OptionsAssigner assigner(&options_);
std::string value(TestFileManager::getInputFilePath("selfile.dat"));
ASSERT_NO_THROW_GMX(options_.addOption(
SelectionOption("optsel").storeVector(&optsel)
.multiValue()));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
ASSERT_NO_THROW_GMX(options_.addOption(
SelectionOption("sel2").storeVector(&sel2)
.multiValue().required()));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
SelectionOption("sel1").storeVector(&sel1).required()));
ASSERT_NO_THROW_GMX(options_.addOption(
SelectionOption("sel2").storeVector(&sel2).required()));
- setManager();
gmx::OptionsAssigner assigner(&options_);
std::string value(TestFileManager::getInputFilePath("selfile.dat"));
using gmx::SelectionOption;
ASSERT_NO_THROW_GMX(options_.addOption(
SelectionOption("sel").storeVector(&sel).multiValue()));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
using gmx::SelectionOption;
ASSERT_NO_THROW_GMX(options_.addOption(
SelectionOption("sel").storeVector(&sel).multiValue()));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
using gmx::SelectionOption;
ASSERT_NO_THROW_GMX(options_.addOption(
SelectionOption("sel").storeVector(&sel).multiValue()));
- setManager();
gmx::OptionsAssigner assigner(&options_);
EXPECT_NO_THROW_GMX(assigner.start());
SelectionCollection *selections,
int *argc, char *argv[])
{
- Options options(NULL, NULL);
- Options moduleOptions(module_->name(), module_->description());
- Options commonOptions("common", "Common analysis control");
- Options selectionOptions("selection", "Common selection control");
- module_->initOptions(&moduleOptions, settings);
- common->initOptions(&commonOptions);
- selections->initOptions(&selectionOptions);
+ SelectionOptionManager seloptManager(selections);
+ Options options(NULL, NULL);
+ Options moduleOptions(module_->name(), module_->description());
+ Options commonOptions("common", "Common analysis control");
+ Options selectionOptions("selection", "Common selection control");
+ options.addManager(&seloptManager);
options.addSubSection(&commonOptions);
options.addSubSection(&selectionOptions);
options.addSubSection(&moduleOptions);
- SelectionOptionManager seloptManager(selections);
- setManagerForSelectionOptions(&options, &seloptManager);
+ module_->initOptions(&moduleOptions, settings);
+ common->initOptions(&commonOptions);
+ selections->initOptions(&selectionOptions);
{
CommandLineParser parser(&options);
TrajectoryAnalysisSettings settings;
TrajectoryAnalysisRunnerCommon common(&settings);
- Options options(NULL, NULL);
- Options moduleOptions(impl_->module_->name(), impl_->module_->description());
- Options commonOptions("common", "Common analysis control");
- Options selectionOptions("selection", "Common selection control");
-
- impl_->module_->initOptions(&moduleOptions, &settings);
- common.initOptions(&commonOptions);
- selections.initOptions(&selectionOptions);
+ SelectionOptionManager seloptManager(&selections);
+ Options options(NULL, NULL);
+ Options moduleOptions(impl_->module_->name(), impl_->module_->description());
+ Options commonOptions("common", "Common analysis control");
+ Options selectionOptions("selection", "Common selection control");
+ options.addManager(&seloptManager);
options.addSubSection(&commonOptions);
options.addSubSection(&selectionOptions);
options.addSubSection(&moduleOptions);
- SelectionOptionManager seloptManager(&selections);
- setManagerForSelectionOptions(&options, &seloptManager);
+ impl_->module_->initOptions(&moduleOptions, &settings);
+ common.initOptions(&commonOptions);
+ selections.initOptions(&selectionOptions);
CommandLineHelpWriter(options)
.setShowDescriptions(true)