$search
00001 /****************************************************************************** 00002 * 00003 * file: MultiArg.h 00004 * 00005 * Copyright (c) 2003, Michael E. Smoot . 00006 * Copyright (c) 2004, Michael E. Smoot, Daniel Aarno. 00007 * All rights reverved. 00008 * 00009 * See the file COPYING in the top directory of this distribution for 00010 * more information. 00011 * 00012 * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS 00013 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00014 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00015 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00016 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00017 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00018 * DEALINGS IN THE SOFTWARE. 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 // always take the first one, regardless of start string 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 // continuing taking the args until we hit one with a start string 00343 while ( (unsigned int)(*i)+1 < args.size() && 00344 args[(*i)+1].find_first_of( Arg::flagStartString() ) != 0 && 00345 args[(*i)+1].find_first_of( Arg::nameStartString() ) != 0 ) 00346 _extractValue( args[++(*i)] ); 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); // Ignore input, don't warn 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); // Ignore input, don't warn 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 } // namespace TCLAP 00432 00433 #endif