diff --git a/include/tclap/MultiArg.h b/include/tclap/MultiArg.h index 045dda3..3f3984a 100644 --- a/include/tclap/MultiArg.h +++ b/include/tclap/MultiArg.h @@ -27,6 +27,7 @@ #include #include +#include #ifdef HAVE_CONFIG_H #include @@ -172,19 +173,16 @@ class MultiArg : public Arg */ std::vector _values; - /** - * A list of allowed values. - * A list of values allowed for this argument. If the value parsed - * for this arg is not found in this list, then an exception is - * thrown. If the list is empty, then any value is allowed. - */ - std::vector _allowed; - /** * The description of type T to be used in the usage. */ std::string _typeDesc; + /** + * A list of constraint on this Arg. + */ + Constraint* _constraint; + /** * Extracts the value from the string. * Attempts to parse string as type T, if this fails an exception @@ -193,12 +191,6 @@ class MultiArg : public Arg */ void _extractValue( const std::string& val ); - /** - * Checks to see if parsed value is in allowed list. - * \param val - value parsed (only used in output). - */ - void _checkAllowed( const std::string& val ); - public: /** @@ -261,8 +253,8 @@ class MultiArg : public Arg * does. * \param req - Whether the argument is required on the command * line. - * \param allowed - A vector of type T that where the values in the - * vector are the only values allowed for the arg. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. * \param v - An optional visitor. You probably should not * use this unless you have a very good reason. */ @@ -270,7 +262,7 @@ class MultiArg : public Arg const std::string& name, const std::string& desc, bool req, - const std::vector& allowed, + Constraint* constraint, Visitor* v = NULL ); /** @@ -283,8 +275,8 @@ class MultiArg : public Arg * does. * \param req - Whether the argument is required on the command * line. - * \param allowed - A vector of type T that where the values in the - * vector are the only values allowed for the arg. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. * \param parser - A CmdLine parser object to add this Arg to * \param v - An optional visitor. You probably should not * use this unless you have a very good reason. @@ -293,7 +285,7 @@ class MultiArg : public Arg const std::string& name, const std::string& desc, bool req, - const std::vector& allowed, + Constraint* constraint, CmdLineInterface& parser, Visitor* v = NULL ); @@ -331,45 +323,8 @@ class MultiArg : public Arg */ virtual bool isRequired() const; - private: - - /** - * Common initialization code for constructors with allowed vectors. - */ - void allowedInit(); }; -/** - * - */ -template -void MultiArg::allowedInit() -{ - for ( unsigned int i = 0; i < _allowed.size(); i++ ) - { - -#if defined(HAVE_SSTREAM) - std::ostringstream os; -#elif defined(HAVE_STRSTREAM) - std::ostrstream os; -#else -#error "Need a stringstream (sstream or strstream) to compile!" -#endif - - os << _allowed[i]; - - std::string temp( os.str() ); - - if ( i > 0 ) - _typeDesc += "|"; - - _typeDesc += temp; - } -} - -/** - * - */ template MultiArg::MultiArg(const std::string& flag, const std::string& name, @@ -378,7 +333,8 @@ MultiArg::MultiArg(const std::string& flag, const std::string& typeDesc, Visitor* v) : Arg( flag, name, desc, req, true, v ), - _typeDesc( typeDesc ) + _typeDesc( typeDesc ), + _constraint( NULL ) { } template @@ -390,7 +346,8 @@ MultiArg::MultiArg(const std::string& flag, CmdLineInterface& parser, Visitor* v) : Arg( flag, name, desc, req, true, v ), - _typeDesc( typeDesc ) + _typeDesc( typeDesc ), + _constraint( NULL ) { parser.add( this ); } @@ -403,38 +360,29 @@ MultiArg::MultiArg(const std::string& flag, const std::string& name, const std::string& desc, bool req, - const std::vector& allowed, + Constraint* constraint, Visitor* v) : Arg( flag, name, desc, req, true, v ), - _allowed( allowed ) -{ - allowedInit(); -} + _constraint( constraint ) +{ } template MultiArg::MultiArg(const std::string& flag, const std::string& name, const std::string& desc, bool req, - const std::vector& allowed, + Constraint* constraint, CmdLineInterface& parser, Visitor* v) : Arg( flag, name, desc, req, true, v ), - _allowed( allowed ) + _constraint( constraint ) { - allowedInit(); parser.add( this ); } -/** - * - */ template const std::vector& MultiArg::getValue() { return _values; } -/** - * - */ template bool MultiArg::processArg(int *i, std::vector& args) { @@ -476,19 +424,6 @@ bool MultiArg::processArg(int *i, std::vector& args) return false; } -/** - * Checks to see if the value parsed is in the allowed list. - */ -template -void MultiArg::_checkAllowed( const std::string& val ) -{ - if ( _allowed.size() > 0 ) - if ( find(_allowed.begin(),_allowed.end(),_values.back()) - == _allowed.end() ) - throw( CmdLineParseException( "Couldn't find '" + val + - "' in allowed list.", toString() ) ); -} - /** * */ @@ -545,7 +480,11 @@ void MultiArg::_extractValue( const std::string& val ) throw( ArgParseException("More than one valid value " "parsed from string '" + val + "'", toString() ) ); - _checkAllowed( val ); + if ( _constraint != NULL ) + if ( ! _constraint->check( _values.back() ) ) + throw( CmdLineParseException( "Value '" + val + + "' does not meet constraint: " + + _constraint->description() ) ); } diff --git a/include/tclap/UnlabeledMultiArg.h b/include/tclap/UnlabeledMultiArg.h index 5b5bb8e..5a9eea3 100644 --- a/include/tclap/UnlabeledMultiArg.h +++ b/include/tclap/UnlabeledMultiArg.h @@ -99,8 +99,8 @@ class UnlabeledMultiArg : public MultiArg * identification, not as a long flag. * \param desc - A description of what the argument is for or * does. - * \param allowed - A vector of type T that where the values in the - * vector are the only values allowed for the arg. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. * \param ignoreable - Whether or not this argument can be ignored * using the "--" flag. * \param v - An optional visitor. You probably should not @@ -108,7 +108,7 @@ class UnlabeledMultiArg : public MultiArg */ UnlabeledMultiArg( const std::string& name, const std::string& desc, - const std::vector& allowed, + Constraint* constraint, bool ignoreable = false, Visitor* v = NULL ); @@ -118,8 +118,8 @@ class UnlabeledMultiArg : public MultiArg * identification, not as a long flag. * \param desc - A description of what the argument is for or * does. - * \param allowed - A vector of type T that where the values in the - * vector are the only values allowed for the arg. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. * \param parser - A CmdLine parser object to add this Arg to * \param ignoreable - Whether or not this argument can be ignored * using the "--" flag. @@ -128,7 +128,7 @@ class UnlabeledMultiArg : public MultiArg */ UnlabeledMultiArg( const std::string& name, const std::string& desc, - const std::vector& allowed, + Constraint* constraint, CmdLineInterface& parser, bool ignoreable = false, Visitor* v = NULL ); @@ -196,10 +196,10 @@ UnlabeledMultiArg::UnlabeledMultiArg(const std::string& name, template UnlabeledMultiArg::UnlabeledMultiArg(const std::string& name, const std::string& desc, - const std::vector& allowed, + Constraint* constraint, bool ignoreable, Visitor* v) -: MultiArg("", name, desc, false, allowed, v) +: MultiArg("", name, desc, false, constraint, v) { _ignoreable = ignoreable; } @@ -207,11 +207,11 @@ UnlabeledMultiArg::UnlabeledMultiArg(const std::string& name, template UnlabeledMultiArg::UnlabeledMultiArg(const std::string& name, const std::string& desc, - const std::vector& allowed, + Constraint* constraint, CmdLineInterface& parser, bool ignoreable, Visitor* v) -: MultiArg("", name, desc, false, allowed, v) +: MultiArg("", name, desc, false, constraint, v) { _ignoreable = ignoreable; parser.add( this ); diff --git a/include/tclap/UnlabeledValueArg.h b/include/tclap/UnlabeledValueArg.h index 6899a3b..fb9cffd 100644 --- a/include/tclap/UnlabeledValueArg.h +++ b/include/tclap/UnlabeledValueArg.h @@ -127,8 +127,8 @@ class UnlabeledValueArg : public ValueArg * does. * \param value - The default value assigned to this argument if it * is not present on the command line. - * \param allowed - A vector of type T that where the values in the - * vector are the only values allowed for the arg. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. * \param ignoreable - Allows you to specify that this argument can be * ignored if the '--' flag is set. This defaults to false (cannot * be ignored) and should generally stay that way unless you have @@ -139,7 +139,7 @@ class UnlabeledValueArg : public ValueArg UnlabeledValueArg( const std::string& name, const std::string& desc, T value, - const std::vector& allowed, + Constraint* constraint, bool ignoreable = false, Visitor* v = NULL ); @@ -156,8 +156,8 @@ class UnlabeledValueArg : public ValueArg * does. * \param value - The default value assigned to this argument if it * is not present on the command line. - * \param allowed - A vector of type T that where the values in the - * vector are the only values allowed for the arg. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. * \param parser - A CmdLine parser object to add this Arg to * \param ignoreable - Allows you to specify that this argument can be * ignored if the '--' flag is set. This defaults to false (cannot @@ -169,7 +169,7 @@ class UnlabeledValueArg : public ValueArg UnlabeledValueArg( const std::string& name, const std::string& desc, T value, - const std::vector& allowed, + Constraint* constraint, CmdLineInterface& parser, bool ignoreable = false, Visitor* v = NULL); @@ -242,10 +242,10 @@ template UnlabeledValueArg::UnlabeledValueArg(const std::string& name, const std::string& desc, T val, - const std::vector& allowed, + Constraint* constraint, bool ignoreable, Visitor* v) -: ValueArg("", name, desc, true, val, allowed, v) +: ValueArg("", name, desc, true, val, constraint, v) { _ignoreable = ignoreable; } @@ -254,11 +254,11 @@ template UnlabeledValueArg::UnlabeledValueArg(const std::string& name, const std::string& desc, T val, - const std::vector& allowed, + Constraint* constraint, CmdLineInterface& parser, bool ignoreable, Visitor* v) -: ValueArg("", name, desc, true, val, allowed, v) +: ValueArg("", name, desc, true, val, constraint, v) { _ignoreable = ignoreable; parser.add( this ); diff --git a/include/tclap/ValueArg.h b/include/tclap/ValueArg.h index e1f8835..575f61b 100644 --- a/include/tclap/ValueArg.h +++ b/include/tclap/ValueArg.h @@ -27,6 +27,7 @@ #include #include +#include #ifdef HAVE_CONFIG_H #include @@ -177,14 +178,6 @@ class ValueArg : public Arg */ T _value; - /** - * A list of allowed values. - * A list of values allowed for this argument. If the value parsed - * for this arg is not found in this list, then an exception is - * thrown. If the list is empty, then any value is allowed. - */ - std::vector _allowed; - /** * A human readable description of the type to be parsed. * This is a hack, plain and simple. Ideally we would use RTTI to @@ -194,6 +187,11 @@ class ValueArg : public Arg */ std::string _typeDesc; + /** + * A Constraint this Arg must conform to. + */ + Constraint* _constraint; + /** * Extracts the value from the string. * Attempts to parse string as type T, if this fails an exception @@ -202,12 +200,6 @@ class ValueArg : public Arg */ void _extractValue( const std::string& val ); - /** - * Checks to see if parsed value is in allowed list. - * \param val - value parsed (only used in output). - */ - void _checkAllowed( const std::string& val ); - public: /** @@ -291,8 +283,8 @@ class ValueArg : public Arg * line. * \param value - The default value assigned to this argument if it * is not present on the command line. - * \param allowed - A vector of type T that where the values in the - * vector are the only values allowed for the arg. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. * \param parser - A CmdLine parser object to add this Arg to. * \param v - An optional visitor. You probably should not * use this unless you have a very good reason. @@ -302,7 +294,7 @@ class ValueArg : public Arg const std::string& desc, bool req, T value, - const std::vector& allowed, + Constraint* constraint, CmdLineInterface& parser, Visitor* v = NULL ); @@ -322,8 +314,8 @@ class ValueArg : public Arg * line. * \param value - The default value assigned to this argument if it * is not present on the command line. - * \param allowed - A vector of type T that where the values in the - * vector are the only values allowed for the arg. + * \param constraint - A pointer to a Constraint object used + * to constrain this Arg. * \param v - An optional visitor. You probably should not * use this unless you have a very good reason. */ @@ -332,7 +324,7 @@ class ValueArg : public Arg const std::string& desc, bool req, T value, - const std::vector& allowed, + Constraint* constraint, Visitor* v = NULL ); /** @@ -363,40 +355,9 @@ class ValueArg : public Arg */ virtual std::string longID(const std::string& val = "val") const; - private: - - /** - * Common initialization code for constructors with allowed vectors. - */ - void allowedInit(); - }; -template -void ValueArg::allowedInit() -{ - for ( unsigned int i = 0; i < _allowed.size(); i++ ) - { - -#if defined(HAVE_SSTREAM) - std::ostringstream os; -#elif defined(HAVE_STRSTREAM) - std::ostrstream os; -#else -#error "Need a stringstream (sstream or strstream) to compile!" -#endif - - os << _allowed[i]; - - std::string temp( os.str() ); - - if ( i > 0 ) - _typeDesc += "|"; - _typeDesc += temp; - } -} - /** * Constructor implementation. */ @@ -410,7 +371,8 @@ ValueArg::ValueArg(const std::string& flag, Visitor* v) : Arg(flag, name, desc, req, true, v), _value( val ), - _typeDesc( typeDesc ) + _typeDesc( typeDesc ), + _constraint( NULL ) { } template @@ -424,28 +386,24 @@ ValueArg::ValueArg(const std::string& flag, Visitor* v) : Arg(flag, name, desc, req, true, v), _value( val ), - _typeDesc( typeDesc ) + _typeDesc( typeDesc ), + _constraint( NULL ) { parser.add( this ); } -/** - * Constructor with allowed list. - */ template ValueArg::ValueArg(const std::string& flag, const std::string& name, const std::string& desc, bool req, T val, - const std::vector& allowed, + Constraint* constraint, Visitor* v) : Arg(flag, name, desc, req, true, v), _value( val ), - _allowed( allowed ) -{ - allowedInit(); -} + _constraint( constraint ) +{ } template ValueArg::ValueArg(const std::string& flag, @@ -453,14 +411,13 @@ ValueArg::ValueArg(const std::string& flag, const std::string& desc, bool req, T val, - const std::vector& allowed, + Constraint* constraint, CmdLineInterface& parser, Visitor* v) : Arg(flag, name, desc, req, true, v), _value( val ), -_allowed( allowed ) +_constraint( constraint ) { - allowedInit(); parser.add( this ); } @@ -518,18 +475,6 @@ bool ValueArg::processArg(int *i, std::vector& args) return false; } -/** - * Checks to see if the value parsed is in the allowed list. - */ -template -void ValueArg::_checkAllowed( const std::string& val ) -{ - if ( _allowed.size() > 0 ) - if ( find(_allowed.begin(),_allowed.end(),_value) == _allowed.end() ) - throw( CmdLineParseException( "Couldn't find '" + val + - "' in allowed list.", toString() ) ); -} - /** * Implementation of shortID. */ @@ -564,7 +509,11 @@ void ValueArg::_extractValue( const std::string& val ) "More than one valid value parsed from string '" + val + "'", toString() ) ); - _checkAllowed( val ); + if ( _constraint != NULL ) + if ( ! _constraint->check( _value ) ) + throw( CmdLineParseException( "Value '" + val + + "' does not meet constraint: " + + _constraint->description() ) ); } } // namespace TCLAP