tclap  1.2.1
MultiArg.h
Go to the documentation of this file.
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