BASIS  version 1.2.3 (revision 2104)
ValueArg.h
00001 /****************************************************************************** 
00002  * 
00003  *  file:  ValueArg.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_VALUE_ARGUMENT_H
00024 #define TCLAP_VALUE_ARGUMENT_H
00025 
00026 #include <string>
00027 #include <vector>
00028 
00029 #include <sbia/tclap/Arg.h>
00030 #include <sbia/tclap/Constraint.h>
00031 
00032 namespace TCLAP {
00033 
00034 /**
00035  * The basic labeled argument that parses a value.
00036  * This is a template class, which means the type T defines the type
00037  * that a given object will attempt to parse when the flag/name is matched
00038  * on the command line.  While there is nothing stopping you from creating
00039  * an unflagged ValueArg, it is unwise and would cause significant problems.
00040  * Instead use an UnlabeledValueArg.
00041  */
00042 template<class T>
00043 class ValueArg : public Arg 
00044 {
00045     protected:
00046 
00047         /**
00048          * The value parsed from the command line.
00049          * Can be of any type, as long as the >> operator for the type
00050          * is defined.
00051          */
00052         T _value;
00053 
00054         /**
00055          * Used to support the reset() method so that ValueArg can be
00056          * reset to their constructed value.
00057          */
00058         T _default;
00059 
00060         /**
00061          * A human readable description of the type to be parsed.
00062          * This is a hack, plain and simple.  Ideally we would use RTTI to
00063          * return the name of type T, but until there is some sort of
00064          * consistent support for human readable names, we are left to our
00065          * own devices.
00066          */
00067         std::string _typeDesc;
00068 
00069         /**
00070          * A Constraint this Arg must conform to. 
00071          */
00072         Constraint<T>* _constraint;
00073 
00074         /**
00075          * Extracts the value from the string.
00076          * Attempts to parse string as type T, if this fails an exception
00077          * is thrown.
00078          * \param val - value to be parsed. 
00079          */
00080         void _extractValue( const std::string& val );
00081 
00082     public:
00083 
00084         /**
00085          * Labeled ValueArg constructor.
00086          * You could conceivably call this constructor with a blank flag, 
00087          * but that would make you a bad person.  It would also cause
00088          * an exception to be thrown.   If you want an unlabeled argument, 
00089          * use the other constructor.
00090          * \param flag - The one character flag that identifies this
00091          * argument on the command line.
00092          * \param name - A one word name for the argument.  Can be
00093          * used as a long flag on the command line.
00094          * \param desc - A description of what the argument is for or
00095          * does.
00096          * \param req - Whether the argument is required on the command
00097          * line.
00098          * \param value - The default value assigned to this argument if it
00099          * is not present on the command line.
00100          * \param typeDesc - A short, human readable description of the
00101          * type that this object expects.  This is used in the generation
00102          * of the USAGE statement.  The goal is to be helpful to the end user
00103          * of the program.
00104          * \param v - An optional visitor.  You probably should not
00105          * use this unless you have a very good reason.
00106          */
00107         ValueArg( const std::string& flag, 
00108                   const std::string& name, 
00109                   const std::string& desc, 
00110                   bool req, 
00111                   T value,
00112                   const std::string& typeDesc,
00113                   Visitor* v = NULL);
00114                  
00115                  
00116         /**
00117          * Labeled ValueArg constructor.
00118          * You could conceivably call this constructor with a blank flag, 
00119          * but that would make you a bad person.  It would also cause
00120          * an exception to be thrown.   If you want an unlabeled argument, 
00121          * use the other constructor.
00122          * \param flag - The one character flag that identifies this
00123          * argument on the command line.
00124          * \param name - A one word name for the argument.  Can be
00125          * used as a long flag on the command line.
00126          * \param desc - A description of what the argument is for or
00127          * does.
00128          * \param req - Whether the argument is required on the command
00129          * line.
00130          * \param value - The default value assigned to this argument if it
00131          * is not present on the command line.
00132          * \param typeDesc - A short, human readable description of the
00133          * type that this object expects.  This is used in the generation
00134          * of the USAGE statement.  The goal is to be helpful to the end user
00135          * of the program.
00136          * \param parser - A CmdLine parser object to add this Arg to
00137          * \param v - An optional visitor.  You probably should not
00138          * use this unless you have a very good reason.
00139          */
00140         ValueArg( const std::string& flag, 
00141                   const std::string& name, 
00142                   const std::string& desc, 
00143                   bool req, 
00144                   T value,
00145                   const std::string& typeDesc,
00146                   CmdLineInterface& parser,
00147                   Visitor* v = NULL );
00148  
00149         /**
00150          * Labeled ValueArg constructor.
00151          * You could conceivably call this constructor with a blank flag, 
00152          * but that would make you a bad person.  It would also cause
00153          * an exception to be thrown.   If you want an unlabeled argument, 
00154          * use the other constructor.
00155          * \param flag - The one character flag that identifies this
00156          * argument on the command line.
00157          * \param name - A one word name for the argument.  Can be
00158          * used as a long flag on the command line.
00159          * \param desc - A description of what the argument is for or
00160          * does.
00161          * \param req - Whether the argument is required on the command
00162          * line.
00163          * \param value - The default value assigned to this argument if it
00164          * is not present on the command line.
00165          * \param constraint - A pointer to a Constraint object used
00166          * to constrain this Arg.
00167          * \param parser - A CmdLine parser object to add this Arg to.
00168          * \param v - An optional visitor.  You probably should not
00169          * use this unless you have a very good reason.
00170          */
00171         ValueArg( const std::string& flag, 
00172                   const std::string& name, 
00173                   const std::string& desc, 
00174                   bool req, 
00175                   T value,
00176                   Constraint<T>* constraint,
00177                   CmdLineInterface& parser,
00178                   Visitor* v = NULL );
00179       
00180         /**
00181          * Labeled ValueArg constructor.
00182          * You could conceivably call this constructor with a blank flag, 
00183          * but that would make you a bad person.  It would also cause
00184          * an exception to be thrown.   If you want an unlabeled argument, 
00185          * use the other constructor.
00186          * \param flag - The one character flag that identifies this
00187          * argument on the command line.
00188          * \param name - A one word name for the argument.  Can be
00189          * used as a long flag on the command line.
00190          * \param desc - A description of what the argument is for or
00191          * does.
00192          * \param req - Whether the argument is required on the command
00193          * line.
00194          * \param value - The default value assigned to this argument if it
00195          * is not present on the command line.
00196          * \param constraint - A pointer to a Constraint object used
00197          * to constrain this Arg.
00198          * \param v - An optional visitor.  You probably should not
00199          * use this unless you have a very good reason.
00200          */
00201         ValueArg( const std::string& flag, 
00202                   const std::string& name, 
00203                   const std::string& desc, 
00204                   bool req, 
00205                   T value,
00206                   Constraint<T>* constraint,
00207                   Visitor* v = NULL );
00208 
00209         /**
00210          * Handles the processing of the argument.
00211          * This re-implements the Arg version of this method to set the
00212          * _value of the argument appropriately.  It knows the difference
00213          * between labeled and unlabeled.
00214          * \param i - Pointer the the current argument in the list.
00215          * \param args - Mutable list of strings. Passed 
00216          * in from main().
00217          */
00218         virtual bool processArg(int* i, std::vector<std::string>& args); 
00219 
00220         /**
00221          * Returns the value of the argument.
00222          */
00223         T& getValue() ;
00224 
00225         /**
00226          * Specialization of shortID.
00227          * \param val - value to be used.
00228          */
00229         virtual std::string shortID(const std::string& val = "val") const;
00230 
00231         /**
00232          * Specialization of longID.
00233          * \param val - value to be used.
00234          */
00235         virtual std::string longID(const std::string& val = "val") const;
00236         
00237         virtual void reset() ;
00238 
00239 private:
00240        /**
00241         * Prevent accidental copying
00242         */
00243        ValueArg<T>(const ValueArg<T>& rhs);
00244        ValueArg<T>& operator=(const ValueArg<T>& rhs);
00245 };
00246 
00247 
00248 template<class T>
00249 ValueArg<T>::ValueArg(const std::string& flag, 
00250                       const std::string& name, 
00251                       const std::string& desc, 
00252                       bool req, 
00253                       T val,
00254                       const std::string& typeDesc,
00255                       Visitor* v)
00256 : Arg(flag, name, desc, req, true, v),
00257   _value( val ),
00258   _default( val ),
00259   _typeDesc( typeDesc ),
00260   _constraint( NULL )
00261 { }
00262 
00263 template<class T>
00264 ValueArg<T>::ValueArg(const std::string& flag, 
00265                       const std::string& name, 
00266                       const std::string& desc, 
00267                       bool req, 
00268                       T val,
00269                       const std::string& typeDesc,
00270                       CmdLineInterface& parser,
00271                       Visitor* v)
00272 : Arg(flag, name, desc, req, true, v),
00273   _value( val ),
00274   _default( val ),
00275   _typeDesc( typeDesc ),
00276   _constraint( NULL )
00277 { 
00278     parser.add( this );
00279 }
00280 
00281 template<class T>
00282 ValueArg<T>::ValueArg(const std::string& flag, 
00283                       const std::string& name, 
00284                       const std::string& desc, 
00285                       bool req, 
00286                       T val,
00287                       Constraint<T>* constraint,
00288                       Visitor* v)
00289 : Arg(flag, name, desc, req, true, v),
00290   _value( val ),
00291   _default( val ),
00292   _typeDesc( constraint->shortID() ),
00293   _constraint( constraint )
00294 { }
00295 
00296 template<class T>
00297 ValueArg<T>::ValueArg(const std::string& flag, 
00298                       const std::string& name, 
00299                       const std::string& desc, 
00300                       bool req, 
00301                       T val,
00302                       Constraint<T>* constraint,
00303                       CmdLineInterface& parser,
00304                       Visitor* v)
00305 : Arg(flag, name, desc, req, true, v),
00306   _value( val ),
00307   _default( val ),
00308   _typeDesc( constraint->shortID() ),
00309   _constraint( constraint )
00310 { 
00311     parser.add( this );
00312 }
00313 
00314 template<class T>
00315 T& ValueArg<T>::getValue() { return _value; }
00316 
00317 template<class T>
00318 bool ValueArg<T>::processArg(int *i, std::vector<std::string>& args)
00319 {
00320     if ( _ignoreable && Arg::ignoreRest() )
00321         return false;
00322 
00323     if ( _hasBlanks( args[*i] ) )
00324         return false;
00325 
00326     std::string flag = args[*i];
00327 
00328     std::string value = "";
00329     trimFlag( flag, value );
00330 
00331     if ( argMatches( flag ) )
00332     {
00333         if ( _alreadySet )
00334         {
00335             if ( _xorSet )
00336                 throw( CmdLineParseException(
00337                        "Mutually exclusive argument already set!", 
00338                                              toString()) );
00339             else
00340                 throw( CmdLineParseException("Argument already set!", 
00341                                              toString()) );
00342         }
00343 
00344         if ( Arg::delimiter() != ' ' && value == "" )
00345             throw( ArgParseException( 
00346                             "Couldn't find delimiter for this argument!",
00347                              toString() ) );
00348 
00349         if ( value == "" )
00350         {
00351             (*i)++;
00352             if ( static_cast<unsigned int>(*i) < args.size() ) 
00353                 _extractValue( args[*i] );
00354             else
00355                 throw( ArgParseException("Missing a value for this argument!",
00356                                                     toString() ) );
00357         }
00358         else
00359             _extractValue( value );
00360                 
00361         _alreadySet = true;
00362         _checkWithVisitor();
00363         return true;
00364     }   
00365     else
00366         return false;
00367 }
00368 
00369 template<class T>
00370 std::string ValueArg<T>::shortID(const std::string& val) const
00371 {
00372     static_cast<void>(val); // Ignore input, don't warn
00373     return Arg::shortID( _typeDesc ); 
00374 }
00375 
00376 template<class T>
00377 std::string ValueArg<T>::longID(const std::string& val) const
00378 {
00379     static_cast<void>(val); // Ignore input, don't warn
00380     return Arg::longID( _typeDesc ); 
00381 }
00382 
00383 template<class T>
00384 void ValueArg<T>::_extractValue( const std::string& val ) 
00385 {
00386     try {
00387     ExtractValue(_value, val, typename ArgTraits<T>::ValueCategory());
00388     } catch( ArgParseException &e) {
00389     throw ArgParseException(e.error(), toString());
00390     }
00391     
00392     if ( _constraint != NULL )
00393     if ( ! _constraint->check( _value ) )
00394         throw( CmdLineParseException( "Value '" + val + 
00395                       + "' does not meet constraint: " 
00396                       + _constraint->description(),
00397                       toString() ) );
00398 }
00399 
00400 template<class T>
00401 void ValueArg<T>::reset()
00402 {
00403     Arg::reset();
00404     _value = _default;
00405 }
00406 
00407 } // namespace TCLAP
00408 
00409 #endif