00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef TCLAP_MULTIPLE_ARGUMENT_H
00024 #define TCLAP_MULTIPLE_ARGUMENT_H
00025
00026 #include <string>
00027 #include <vector>
00028
00029 #include <tclap/Arg.h>
00030 #include <tclap/Constraint.h>
00031
00032 namespace TCLAP {
00038 template<class T>
00039 class MultiArg : public Arg
00040 {
00041 public:
00042 typedef std::vector<T> container_type;
00043 typedef typename container_type::iterator iterator;
00044 typedef typename container_type::const_iterator const_iterator;
00045
00046 protected:
00047
00051 std::vector<T> _values;
00052
00056 std::string _typeDesc;
00057
00061 Constraint<T>* _constraint;
00062
00069 void _extractValue( const std::string& val );
00070
00074 bool _allowMore;
00075
00076 public:
00077
00095 MultiArg( const std::string& flag,
00096 const std::string& name,
00097 const std::string& desc,
00098 bool req,
00099 const std::string& typeDesc,
00100 Visitor* v = NULL);
00101
00120 MultiArg( const std::string& flag,
00121 const std::string& name,
00122 const std::string& desc,
00123 bool req,
00124 const std::string& typeDesc,
00125 CmdLineInterface& parser,
00126 Visitor* v = NULL );
00127
00143 MultiArg( const std::string& flag,
00144 const std::string& name,
00145 const std::string& desc,
00146 bool req,
00147 Constraint<T>* constraint,
00148 Visitor* v = NULL );
00149
00166 MultiArg( const std::string& flag,
00167 const std::string& name,
00168 const std::string& desc,
00169 bool req,
00170 Constraint<T>* constraint,
00171 CmdLineInterface& parser,
00172 Visitor* v = NULL );
00173
00182 virtual bool processArg(int* i, std::vector<std::string>& args);
00183
00188 const std::vector<T>& getValue();
00189
00194 const_iterator begin() const { return _values.begin(); }
00195
00200 const_iterator end() const { return _values.end(); }
00201
00206 virtual std::string shortID(const std::string& val="val") const;
00207
00212 virtual std::string longID(const std::string& val="val") const;
00213
00218 virtual bool isRequired() const;
00219
00220 virtual bool allowMore();
00221
00222 virtual void reset();
00223
00224 private:
00228 MultiArg<T>(const MultiArg<T>& rhs);
00229 MultiArg<T>& operator=(const MultiArg<T>& rhs);
00230
00231 };
00232
00233 template<class T>
00234 MultiArg<T>::MultiArg(const std::string& flag,
00235 const std::string& name,
00236 const std::string& desc,
00237 bool req,
00238 const std::string& typeDesc,
00239 Visitor* v) :
00240 Arg( flag, name, desc, req, true, v ),
00241 _values(std::vector<T>()),
00242 _typeDesc( typeDesc ),
00243 _constraint( NULL ),
00244 _allowMore(false)
00245 {
00246 _acceptsMultipleValues = true;
00247 }
00248
00249 template<class T>
00250 MultiArg<T>::MultiArg(const std::string& flag,
00251 const std::string& name,
00252 const std::string& desc,
00253 bool req,
00254 const std::string& typeDesc,
00255 CmdLineInterface& parser,
00256 Visitor* v)
00257 : Arg( flag, name, desc, req, true, v ),
00258 _values(std::vector<T>()),
00259 _typeDesc( typeDesc ),
00260 _constraint( NULL ),
00261 _allowMore(false)
00262 {
00263 parser.add( this );
00264 _acceptsMultipleValues = true;
00265 }
00266
00270 template<class T>
00271 MultiArg<T>::MultiArg(const std::string& flag,
00272 const std::string& name,
00273 const std::string& desc,
00274 bool req,
00275 Constraint<T>* constraint,
00276 Visitor* v)
00277 : Arg( flag, name, desc, req, true, v ),
00278 _values(std::vector<T>()),
00279 _typeDesc( constraint->shortID() ),
00280 _constraint( constraint ),
00281 _allowMore(false)
00282 {
00283 _acceptsMultipleValues = true;
00284 }
00285
00286 template<class T>
00287 MultiArg<T>::MultiArg(const std::string& flag,
00288 const std::string& name,
00289 const std::string& desc,
00290 bool req,
00291 Constraint<T>* constraint,
00292 CmdLineInterface& parser,
00293 Visitor* v)
00294 : Arg( flag, name, desc, req, true, v ),
00295 _values(std::vector<T>()),
00296 _typeDesc( constraint->shortID() ),
00297 _constraint( constraint ),
00298 _allowMore(false)
00299 {
00300 parser.add( this );
00301 _acceptsMultipleValues = true;
00302 }
00303
00304 template<class T>
00305 const std::vector<T>& MultiArg<T>::getValue() { return _values; }
00306
00307 template<class T>
00308 bool MultiArg<T>::processArg(int *i, std::vector<std::string>& args)
00309 {
00310 if ( _ignoreable && Arg::ignoreRest() )
00311 return false;
00312
00313 if ( _hasBlanks( args[*i] ) )
00314 return false;
00315
00316 std::string flag = args[*i];
00317 std::string value = "";
00318
00319 trimFlag( flag, value );
00320
00321 if ( argMatches( flag ) )
00322 {
00323 if ( Arg::delimiter() != ' ' && value == "" )
00324 throw( ArgParseException(
00325 "Couldn't find delimiter for this argument!",
00326 toString() ) );
00327
00328
00329 if ( value == "" )
00330 {
00331 (*i)++;
00332 if ( static_cast<unsigned int>(*i) < args.size() )
00333 _extractValue( args[*i] );
00334 else
00335 throw( ArgParseException("Missing a value for this argument!",
00336 toString() ) );
00337 }
00338 else
00339 _extractValue( value );
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 _alreadySet = true;
00350 _checkWithVisitor();
00351
00352 return true;
00353 }
00354 else
00355 return false;
00356 }
00357
00361 template<class T>
00362 std::string MultiArg<T>::shortID(const std::string& val) const
00363 {
00364 static_cast<void>(val);
00365 return Arg::shortID(_typeDesc) + " ... ";
00366 }
00367
00371 template<class T>
00372 std::string MultiArg<T>::longID(const std::string& val) const
00373 {
00374 static_cast<void>(val);
00375 return Arg::longID(_typeDesc) + " (accepted multiple times)";
00376 }
00377
00382 template<class T>
00383 bool MultiArg<T>::isRequired() const
00384 {
00385 if ( _required )
00386 {
00387 if ( _values.size() > 1 )
00388 return false;
00389 else
00390 return true;
00391 }
00392 else
00393 return false;
00394
00395 }
00396
00397 template<class T>
00398 void MultiArg<T>::_extractValue( const std::string& val )
00399 {
00400 try {
00401 T tmp;
00402 ExtractValue(tmp, val, typename ArgTraits<T>::ValueCategory());
00403 _values.push_back(tmp);
00404 } catch( ArgParseException &e) {
00405 throw ArgParseException(e.error(), toString());
00406 }
00407
00408 if ( _constraint != NULL )
00409 if ( ! _constraint->check( _values.back() ) )
00410 throw( CmdLineParseException( "Value '" + val +
00411 "' does not meet constraint: " +
00412 _constraint->description(),
00413 toString() ) );
00414 }
00415
00416 template<class T>
00417 bool MultiArg<T>::allowMore()
00418 {
00419 bool am = _allowMore;
00420 _allowMore = true;
00421 return am;
00422 }
00423
00424 template<class T>
00425 void MultiArg<T>::reset()
00426 {
00427 Arg::reset();
00428 _values.clear();
00429 }
00430
00431 }
00432
00433 #endif