+++ /dev/null
-template
-Makefile.*-*
+++ /dev/null
-analysisdata-tests
* point when the actual option is created.
*
* Subclasses should override createStorage() to create the correct type
- * of storage object.
+ * of storage object. If they use their own info type derived from OptionInfo,
+ * they should also have a public typedef \c InfoType that specifies that
+ * info type. This is required for Options::addOption() to return the correct
+ * info type.
*
* \ingroup module_options
*/
#include "../utility/gmxassert.h"
#include "abstractoption.h"
+#include "basicoptioninfo.h"
namespace gmx
{
class BooleanOption : public OptionTemplate<bool, BooleanOption>
{
public:
+ //! OptionInfo subclass corresponding to this option type.
+ typedef BooleanOptionInfo InfoType;
+
//! Initializes an option with the given name.
explicit BooleanOption(const char *name) : MyBase(name) {}
class IntegerOption : public OptionTemplate<int, IntegerOption>
{
public:
+ //! OptionInfo subclass corresponding to this option type.
+ typedef IntegerOptionInfo InfoType;
+
//! Initializes an option with the given name.
explicit IntegerOption(const char *name) : MyBase(name) {}
class DoubleOption : public OptionTemplate<double, DoubleOption>
{
public:
+ //! OptionInfo subclass corresponding to this option type.
+ typedef DoubleOptionInfo InfoType;
+
//! Initializes an option with the given name.
explicit DoubleOption(const char *name) : MyBase(name), bTime_(false)
{
class StringOption : public OptionTemplate<std::string, StringOption>
{
public:
+ //! OptionInfo subclass corresponding to this option type.
+ typedef StringOptionInfo InfoType;
+
//! Initializes an option with the given name.
explicit StringOption(const char *name)
: MyBase(name), enumValues_(NULL), defaultEnumIndex_(-1),
#include <string>
#include "abstractoption.h"
+#include "filenameoptioninfo.h"
#include "optionfiletype.h"
namespace gmx
class FileNameOption : public OptionTemplate<std::string, FileNameOption>
{
public:
+ //! OptionInfo subclass corresponding to this option type.
+ typedef FileNameOptionInfo InfoType;
+
//! Initializes an option with the given name.
explicit FileNameOption(const char *name)
: MyBase(name), filetype_(eftUnknown),
section->impl_->parent_ = this;
}
-void Options::addOption(const AbstractOption &settings)
+OptionInfo *Options::addOption(const AbstractOption &settings)
{
AbstractOptionStoragePointer option(settings.createStorage());
if (impl_->findOption(option->name().c_str()) != NULL)
GMX_THROW(APIError("Duplicate option: " + option->name()));
}
impl_->options_.push_back(move(option));
+ return &impl_->options_.back()->optionInfo();
}
bool Options::isSet(const char *name) const
#include <string>
#include "../utility/common.h"
+#include "../utility/gmxassert.h"
+
+#include "optioninfo.h"
namespace gmx
{
/*! \brief
* Adds a recognized option to the collection.
*
- * \throws APIError if invalid option settings are provided.
+ * \param[in] settings Option description.
+ * \returns OptionInfo object for the created option (never NULL).
+ * \throws APIError if invalid option settings are provided.
+ *
+ * This method provides the internal implementation, but in most cases
+ * the templated method is called from user code.
+ * See the templated method for more details.
+ */
+ OptionInfo *addOption(const AbstractOption &settings);
+ /*! \brief
+ * Adds a recognized option to the collection.
+ *
+ * \tparam OptionType Type of the options description object.
+ * \param[in] settings Option description.
+ * \returns OptionInfo object for the created option (never NULL).
+ * \throws APIError if invalid option settings are provided.
+ *
+ * The return value is a pointer for more convenient use in callers:
+ * often callers need to declare the variable that will hold the return
+ * value in wider scope than would be achieved by declaring it at the
+ * site where addOption() is called.
+ * The returned pointer must not be freed.
*
* See \link Options class documentation \endlink for example usage.
+ *
+ * \libinternal
+ * \p OptionType::InfoType must specify a type that derives from
+ * OptionInfo and matches the type that is returned by
+ * AbstractOptionStorage::optionInfo() for the storage object that
+ * corresponds to \p OptionType.
*/
- void addOption(const AbstractOption &settings);
+ template <class OptionType>
+ typename OptionType::InfoType *addOption(const OptionType &settings)
+ {
+ OptionInfo *info
+ = addOption(static_cast<const AbstractOption &>(settings));
+ GMX_ASSERT(info->isType<typename OptionType::InfoType>(),
+ "Mismatching option info type declaration and implementation");
+ return info->toType<typename OptionType::InfoType>();
+ }
//! Returns true if option \p name is set.
bool isSet(const char *name) const;
+++ /dev/null
-options-test
#include <gtest/gtest.h>
#include "gromacs/options/abstractoption.h"
+#include "gromacs/options/optioninfo.h"
#include "gromacs/options/options.h"
#include "gromacs/options/optionstoragetemplate.h"
#include "gromacs/options/optionsassigner.h"
{
class MockOption;
+class MockOptionStorage;
+
+class MockOptionInfo : public gmx::OptionInfo
+{
+ public:
+ //! Creates an option info object for the given option.
+ explicit MockOptionInfo(MockOptionStorage *option);
+
+ MockOptionStorage &option();
+};
/*! \internal \brief
* Mock implementation of an option storage class for unit testing.
MyBase::commitValues();
}
+ virtual gmx::OptionInfo &optionInfo() { return info_; }
// These are not used.
- virtual gmx::OptionInfo &optionInfo()
- {
- GMX_THROW(gmx::test::TestException("Not implemented"));
- }
virtual const char *typeString() const { return "mock"; }
virtual std::string formatSingleValue(const std::string &/*value*/) const
{
MOCK_METHOD1(convertValue, void(const std::string &value));
MOCK_METHOD1(processSetValues, void(ValueList *values));
MOCK_METHOD0(processAll, void());
+
+ private:
+ MockOptionInfo info_;
};
/*! \internal \brief
class MockOption : public gmx::OptionTemplate<std::string, MockOption>
{
public:
+ //! OptionInfo subclass corresponding to this option type.
+ typedef MockOptionInfo InfoType;
+
//! Initializes an option with the given name.
explicit MockOption(const char *name)
- : MyBase(name), storagePtr_(NULL)
+ : MyBase(name)
{
}
- //! Sets an output pointer to give access to the created storage object.
- MyClass &storageObject(MockOptionStorage **storagePtr)
- { storagePtr_ = storagePtr; return me(); }
-
private:
virtual gmx::AbstractOptionStoragePointer createStorage() const
{
- MockOptionStorage *storage = new MockOptionStorage(*this);
- if (storagePtr_ != NULL)
- {
- *storagePtr_ = storage;
- }
- return gmx::AbstractOptionStoragePointer(storage);
+ return gmx::AbstractOptionStoragePointer(new MockOptionStorage(*this));
}
-
- MockOptionStorage **storagePtr_;
};
MockOptionStorage::MockOptionStorage(const MockOption &settings)
- : MyBase(settings)
+ : MyBase(settings), info_(this)
{
using ::testing::_;
using ::testing::Invoke;
.WillByDefault(WithArg<0>(Invoke(this, &MockOptionStorage::addValue)));
}
+MockOptionInfo::MockOptionInfo(MockOptionStorage *option)
+ : gmx::OptionInfo(option)
+{
+}
+
+MockOptionStorage &MockOptionInfo::option()
+{
+ return static_cast<MockOptionStorage &>(gmx::OptionInfo::option());
+}
+
/*
* Tests that finish() can set a required option even if the user has not
* provided it.
{
gmx::Options options(NULL, NULL);
std::vector<std::string> values;
- MockOptionStorage *mock = NULL;
- ASSERT_NO_THROW(options.addOption(
- MockOption("name").storageObject(&mock).required()
- .storeVector(&values)));
- ASSERT_TRUE(mock != NULL);
+ MockOptionInfo *info = options.addOption(
+ MockOption("name").required().storeVector(&values));
+ MockOptionStorage *mock = &info->option();
{
::testing::InSequence dummy;
using ::testing::DoAll;
{
gmx::Options options(NULL, NULL);
std::vector<std::string> values;
- MockOptionStorage *mock = NULL;
- ASSERT_NO_THROW(options.addOption(
- MockOption("name").storageObject(&mock)
- .storeVector(&values).multiValue()));
- ASSERT_TRUE(mock != NULL);
+ MockOptionInfo *info = options.addOption(
+ MockOption("name").storeVector(&values).multiValue());
+ MockOptionStorage *mock = &info->option();
{
::testing::InSequence dummy;
using ::testing::ElementsAre;
{
gmx::Options options(NULL, NULL);
std::vector<std::string> values;
- MockOptionStorage *mock = NULL;
- ASSERT_NO_THROW(options.addOption(
- MockOption("name").storageObject(&mock)
- .storeVector(&values).multiValue()));
- ASSERT_TRUE(mock != NULL);
+ MockOptionInfo *info = options.addOption(
+ MockOption("name").storeVector(&values).multiValue());
+ MockOptionStorage *mock = &info->option();
{
::testing::InSequence dummy;
using ::testing::DoAll;
{
gmx::Options options(NULL, NULL);
std::vector<std::string> values;
- MockOptionStorage *mock = NULL;
- ASSERT_NO_THROW(options.addOption(
- MockOption("name").storageObject(&mock)
- .storeVector(&values).valueCount(2)));
- ASSERT_TRUE(mock != NULL);
+ MockOptionInfo *info = options.addOption(
+ MockOption("name").storeVector(&values).valueCount(2));
+ MockOptionStorage *mock = &info->option();
{
::testing::InSequence dummy;
using ::testing::DoAll;
{
gmx::Options options(NULL, NULL);
std::vector<std::string> values;
- MockOptionStorage *mock = NULL;
- ASSERT_NO_THROW(options.addOption(
- MockOption("name").storageObject(&mock)
- .storeVector(&values).valueCount(0)));
- ASSERT_TRUE(mock != NULL);
+ MockOptionInfo *info = options.addOption(
+ MockOption("name").storeVector(&values).valueCount(0));
+ MockOptionStorage *mock = &info->option();
{
::testing::InSequence dummy;
using ::testing::DoAll;
{
GMX_RELEASE_ASSERT(!hasFlag(efOption_MultipleTimes),
"allowMultiple() is not supported for selection options");
- if (settings.infoPtr_ != NULL)
- {
- *settings.infoPtr_ = &info_;
- }
}
#include "../options/abstractoption.h"
#include "selection.h"
#include "selectionenums.h"
+#include "selectionoptioninfo.h"
namespace gmx
{
class SelectionOption : public OptionTemplate<Selection, SelectionOption>
{
public:
+ //! OptionInfo subclass corresponding to this option type.
+ typedef SelectionOptionInfo InfoType;
+
//! Initializes an option with the given name.
- explicit SelectionOption(const char *name)
- : MyBase(name), infoPtr_(NULL)
- { }
+ explicit SelectionOption(const char *name) : MyBase(name) { }
/*! \brief
* Request velocity evaluation for output positions.
MyClass &dynamicOnlyWhole()
{ selectionFlags_.set(efSelection_DynamicOnlyWhole); return me(); }
- /*! \brief
- * Get an info object that can be used to alter the option after
- * creation.
- *
- * \see SelectionOptionInfo
- */
- MyClass &getAdjuster(SelectionOptionInfo **infoPtr)
- { infoPtr_ = infoPtr; return me(); }
-
private:
// Disable possibility to allow multiple occurrences, since it isn't
// implemented.
virtual AbstractOptionStoragePointer createStorage() const;
SelectionFlags selectionFlags_;
- SelectionOptionInfo **infoPtr_;
/*! \brief
* Needed to initialize SelectionOptionStorage from this class without
+++ /dev/null
-selection-test
TEST_F(SelectionOptionTest, HandlesAdjuster)
{
gmx::SelectionList sel;
- gmx::SelectionOptionInfo *info;
using gmx::SelectionOption;
- ASSERT_NO_THROW(options_.addOption(
- SelectionOption("sel").storeVector(&sel).multiValue()
- .getAdjuster(&info)));
+ gmx::SelectionOptionInfo *info = options_.addOption(
+ SelectionOption("sel").storeVector(&sel).multiValue());
setManager();
gmx::OptionsAssigner assigner(&options_);
TEST_F(SelectionOptionTest, HandlesDynamicWhenStaticRequiredWithAdjuster)
{
gmx::Selection sel;
- gmx::SelectionOptionInfo *info;
using gmx::SelectionOption;
- ASSERT_NO_THROW(options_.addOption(
- SelectionOption("sel").store(&sel)
- .getAdjuster(&info)));
+ gmx::SelectionOptionInfo *info = options_.addOption(
+ SelectionOption("sel").store(&sel));
setManager();
gmx::OptionsAssigner assigner(&options_);
TEST_F(SelectionOptionTest, HandlesTooManySelectionsWithAdjuster)
{
gmx::SelectionList sel;
- gmx::SelectionOptionInfo *info;
using gmx::SelectionOption;
- ASSERT_NO_THROW(options_.addOption(
- SelectionOption("sel").storeVector(&sel).multiValue()
- .getAdjuster(&info)));
+ gmx::SelectionOptionInfo *info = options_.addOption(
+ SelectionOption("sel").storeVector(&sel).multiValue());
setManager();
gmx::OptionsAssigner assigner(&options_);
TEST_F(SelectionOptionTest, HandlesTooFewSelectionsWithAdjuster)
{
gmx::SelectionList sel;
- gmx::SelectionOptionInfo *info;
using gmx::SelectionOption;
- ASSERT_NO_THROW(options_.addOption(
- SelectionOption("sel").storeVector(&sel).multiValue()
- .getAdjuster(&info)));
+ gmx::SelectionOptionInfo *info = options_.addOption(
+ SelectionOption("sel").storeVector(&sel).multiValue());
setManager();
gmx::OptionsAssigner assigner(&options_);
TEST_F(SelectionOptionTest, HandlesDelayedSelectionWithAdjuster)
{
gmx::SelectionList sel;
- gmx::SelectionOptionInfo *info;
using gmx::SelectionOption;
- ASSERT_NO_THROW(options_.addOption(
- SelectionOption("sel").storeVector(&sel).valueCount(3)
- .getAdjuster(&info)));
+ gmx::SelectionOptionInfo *info = options_.addOption(
+ SelectionOption("sel").storeVector(&sel).valueCount(3));
setManager();
gmx::OptionsAssigner assigner(&options_);
options->addOption(BooleanOption("dumpd").store(&bDumpDist_)
.description("Write also distances with -od"));
- options->addOption(SelectionOption("group1").multiValue().required()
- .dynamicOnlyWhole().storeVector(&sel1_).getAdjuster(&sel1info_)
+ sel1info_ = options->addOption(SelectionOption("group1").multiValue()
+ .required().dynamicOnlyWhole().storeVector(&sel1_)
.description("First analysis/vector selection"));
- options->addOption(SelectionOption("group2").multiValue()
- .dynamicOnlyWhole().storeVector(&sel2_).getAdjuster(&sel2info_)
+ sel2info_ = options->addOption(SelectionOption("group2").multiValue()
+ .dynamicOnlyWhole().storeVector(&sel2_)
.description("Second analysis/vector selection"));
}
+++ /dev/null
-g_highway
-g_logo
-g_xrama
-ngmx
+++ /dev/null
-do_dssp
-editconf
-eneconv
-g_anadock
-g_anaeig
-g_analyze
-g_angle
-g_bar
-g_bond
-g_bundle
-g_chi
-g_cluster
-g_clustsize
-g_confrms
-g_covar
-g_current
-g_density
-g_densmap
-g_dielectric
-g_dih
-g_dipoles
-g_disre
-g_dist
-g_dyndom
-g_enemat
-g_energy
-g_filter
-g_gyrate
-g_h2order
-g_hbond
-g_helix
-g_helixorient
-g_kinetics
-g_lie
-g_mdmat
-g_membed
-g_mindist
-g_morph
-g_msd
-g_nmeig
-g_nmens
-g_nmtraj
-g_order
-g_polystat
-g_potential
-g_principal
-g_rama
-g_rdf
-g_rms
-g_rmsdist
-g_rmsf
-g_rotacf
-g_rotmat
-g_saltbr
-g_sas
-g_sdf
-g_select
-g_sgangle
-g_sham
-g_sigeps
-g_sorient
-g_spatial
-g_spol
-g_tcaf
-g_traj
-g_tune_pme
-g_vanhove
-g_velacc
-g_wham
-g_wheel
-genbox
-genconf
-genion
-genrestr
-make_edi
-make_ndx
-mk_angndx
-trjcat
-trjconv
-trjorder
-xpm2ps