Main MRPT website > C++ reference for MRPT 1.4.0
ValueArg.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2016, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 
11 #ifndef TCLAP_VALUE_ARGUMENT_H
12 #define TCLAP_VALUE_ARGUMENT_H
13 
14 #include <string>
15 #include <vector>
16 #include <cstdio> // EOF
17 
20 
21 //#ifdef HAVE_CONFIG_H
22 //#include <config.h>
23 //#else
24 #define HAVE_SSTREAM
25 //#endif
26 
27 #if defined(HAVE_SSTREAM)
28 #include <sstream>
29 #elif defined(HAVE_STRSTREAM)
30 #include <strstream>
31 #else
32 #error "Need a stringstream (sstream or strstream) to compile!"
33 #endif
34 
35 namespace TCLAP {
36 
37 template<class T> class ValueArg;
38 
39 namespace VALUE_ARG_HELPER {
40 
42 
43 /**
44  * This class is used to extract a value from an argument.
45  * It is used because we need a special implementation to
46  * deal with std::string and making a specialiced function
47  * puts it in the T segment, thus generating link errors.
48  * Having a specialiced class makes the symbols weak.
49  * This is not pretty but I don't know how to make it
50  * work any other way.
51  */
52 template<class T> class ValueExtractor
53 {
54  /**
55  *
56  */
57  friend class ValueArg<T>;
58 
59  private:
60 
61  /**
62  * Reference to the value where the result of the extraction will
63  * be put.
64  */
65  T &_value;
66 
67  /**
68  * Constructor.
69  * \param value - Where the value extracted will be put.
70  */
71  ValueExtractor(T &value) : _value(value) { }
72 
73  /**
74  * Method that will attempt to parse the input stream for a value
75  * of type T.
76  * \param val - Where the value parsed will be put.
77  */
78  int extractValue( const std::string& val )
79  {
80 
81 #if defined(HAVE_SSTREAM)
82  std::istringstream is(val);
83 #elif defined(HAVE_STRSTREAM)
84  std::istrstream is(val.c_str());
85 #else
86 #error "Need a stringstream (sstream or strstream) to compile!"
87 #endif
88 
89  int valuesRead = 0;
90  while ( is.good() )
91  {
92  if ( is.peek() != EOF )
93  is >> _value;
94  else
95  break;
96 
97  valuesRead++;
98  }
99 
100  if ( is.fail() )
101  return EXTRACT_FAILURE;
102 
103  if ( valuesRead > 1 )
104  return EXTRACT_TOO_MANY;
105 
106  return 0;
107  }
108 };
109 
110 /**
111  * Specialization for string. This is necessary because istringstream
112  * operator>> is not able to ignore spaces... meaning -x "X Y" will only
113  * read 'X'... and thus the specialization.
114  */
115 template<> class ValueExtractor<std::string>
116 {
117  /**
118  *
119  */
120  friend class ValueArg<std::string>;
121 
122  private:
123 
124  /**
125  * Reference to the value where the result of the extraction will
126  * be put.
127  */
128  std::string &_value;
129 
130  /**
131  * Constructor.
132  * \param value - Where the value extracted will be put.
133  */
134  ValueExtractor(std::string &value) : _value(value) {}
135 
136  /**
137  * Method that will attempt to parse the input stream for a value
138  * of type std::string.
139  * \param val - Where the string parsed will be put.
140  */
141  int extractValue( const std::string& val )
142  {
143  _value = val;
144  return 0;
145  }
146 };
147 
148 } //namespace VALUE_ARG_HELPER
149 
150 /**
151  * The basic labeled argument that parses a value.
152  * This is a template class, which means the type T defines the type
153  * that a given object will attempt to parse when the flag/name is matched
154  * on the command line. While there is nothing stopping you from creating
155  * an unflagged ValueArg, it is unwise and would cause significant problems.
156  * Instead use an UnlabeledValueArg.
157  */
158 template<class T>
159 class ValueArg : public Arg
160 {
161  protected:
162 
163  /**
164  * The value parsed from the command line.
165  * Can be of any type, as long as the >> operator for the type
166  * is defined.
167  */
169 
170  /**
171  * A human readable description of the type to be parsed.
172  * This is a hack, plain and simple. Ideally we would use RTTI to
173  * return the name of type T, but until there is some sort of
174  * consistent support for human readable names, we are left to our
175  * own devices.
176  */
177  std::string _typeDesc;
178 
179  /**
180  * A Constraint this Arg must conform to.
181  */
183 
184  /**
185  * Extracts the value from the string.
186  * Attempts to parse string as type T, if this fails an exception
187  * is thrown.
188  * \param val - value to be parsed.
189  */
190  void _extractValue( const std::string& val );
191 
192  public:
193 
194  /**
195  * Labeled ValueArg constructor.
196  * You could conceivably call this constructor with a blank flag,
197  * but that would make you a bad person. It would also cause
198  * an exception to be thrown. If you want an unlabeled argument,
199  * use the other constructor.
200  * \param flag - The one character flag that identifies this
201  * argument on the command line.
202  * \param name - A one word name for the argument. Can be
203  * used as a long flag on the command line.
204  * \param desc - A description of what the argument is for or
205  * does.
206  * \param req - Whether the argument is required on the command
207  * line.
208  * \param value - The default value assigned to this argument if it
209  * is not present on the command line.
210  * \param typeDesc - A short, human readable description of the
211  * type that this object expects. This is used in the generation
212  * of the USAGE statement. The goal is to be helpful to the end user
213  * of the program.
214  * \param v - An optional visitor. You probably should not
215  * use this unless you have a very good reason.
216  */
217  ValueArg( const std::string& flag,
218  const std::string& name,
219  const std::string& desc,
220  bool req,
221  T value,
222  const std::string& typeDesc,
223  Visitor* v = NULL);
224 
225 
226  /**
227  * Labeled ValueArg constructor.
228  * You could conceivably call this constructor with a blank flag,
229  * but that would make you a bad person. It would also cause
230  * an exception to be thrown. If you want an unlabeled argument,
231  * use the other constructor.
232  * \param flag - The one character flag that identifies this
233  * argument on the command line.
234  * \param name - A one word name for the argument. Can be
235  * used as a long flag on the command line.
236  * \param desc - A description of what the argument is for or
237  * does.
238  * \param req - Whether the argument is required on the command
239  * line.
240  * \param value - The default value assigned to this argument if it
241  * is not present on the command line.
242  * \param typeDesc - A short, human readable description of the
243  * type that this object expects. This is used in the generation
244  * of the USAGE statement. The goal is to be helpful to the end user
245  * of the program.
246  * \param parser - A CmdLine parser object to add this Arg to
247  * \param v - An optional visitor. You probably should not
248  * use this unless you have a very good reason.
249  */
250  ValueArg( const std::string& flag,
251  const std::string& name,
252  const std::string& desc,
253  bool req,
254  T value,
255  const std::string& typeDesc,
256  CmdLineInterface& parser,
257  Visitor* v = NULL );
258 
259  /**
260  * Labeled ValueArg constructor.
261  * You could conceivably call this constructor with a blank flag,
262  * but that would make you a bad person. It would also cause
263  * an exception to be thrown. If you want an unlabeled argument,
264  * use the other constructor.
265  * \param flag - The one character flag that identifies this
266  * argument on the command line.
267  * \param name - A one word name for the argument. Can be
268  * used as a long flag on the command line.
269  * \param desc - A description of what the argument is for or
270  * does.
271  * \param req - Whether the argument is required on the command
272  * line.
273  * \param value - The default value assigned to this argument if it
274  * is not present on the command line.
275  * \param constraint - A pointer to a Constraint object used
276  * to constrain this Arg.
277  * \param parser - A CmdLine parser object to add this Arg to.
278  * \param v - An optional visitor. You probably should not
279  * use this unless you have a very good reason.
280  */
281  ValueArg( const std::string& flag,
282  const std::string& name,
283  const std::string& desc,
284  bool req,
285  T value,
286  Constraint<T>* constraint,
287  CmdLineInterface& parser,
288  Visitor* v = NULL );
289 
290  /**
291  * Labeled ValueArg constructor.
292  * You could conceivably call this constructor with a blank flag,
293  * but that would make you a bad person. It would also cause
294  * an exception to be thrown. If you want an unlabeled argument,
295  * use the other constructor.
296  * \param flag - The one character flag that identifies this
297  * argument on the command line.
298  * \param name - A one word name for the argument. Can be
299  * used as a long flag on the command line.
300  * \param desc - A description of what the argument is for or
301  * does.
302  * \param req - Whether the argument is required on the command
303  * line.
304  * \param value - The default value assigned to this argument if it
305  * is not present on the command line.
306  * \param constraint - A pointer to a Constraint object used
307  * to constrain this Arg.
308  * \param v - An optional visitor. You probably should not
309  * use this unless you have a very good reason.
310  */
311  ValueArg( const std::string& flag,
312  const std::string& name,
313  const std::string& desc,
314  bool req,
315  T value,
316  Constraint<T>* constraint,
317  Visitor* v = NULL );
318 
319  /**
320  * Handles the processing of the argument.
321  * This re-implements the Arg version of this method to set the
322  * _value of the argument appropriately. It knows the difference
323  * between labeled and unlabeled.
324  * \param i - Pointer the the current argument in the list.
325  * \param args - Mutable list of strings. Passed
326  * in from main().
327  */
328  virtual bool processArg(int* i, std::vector<std::string>& args);
329 
330  /**
331  * Returns the value of the argument.
332  */
333  T& getValue() ;
334 
335  /**
336  * Specialization of shortID.
337  * \param val - value to be used.
338  */
339  virtual std::string shortID(const std::string& val = "val") const;
340 
341  /**
342  * Specialization of longID.
343  * \param val - value to be used.
344  */
345  virtual std::string longID(const std::string& val = "val") const;
346 
347 };
348 
349 
350 /**
351  * Constructor implementation.
352  */
353 template<class T>
354 ValueArg<T>::ValueArg(const std::string& flag,
355  const std::string& name,
356  const std::string& desc,
357  bool req,
358  T val,
359  const std::string& typeDesc,
360  Visitor* v)
361 : Arg(flag, name, desc, req, true, v),
362  _value( val ),
363  _typeDesc( typeDesc ),
364  _constraint( NULL )
365 { }
366 
367 template<class T>
368 ValueArg<T>::ValueArg(const std::string& flag,
369  const std::string& name,
370  const std::string& desc,
371  bool req,
372  T val,
373  const std::string& typeDesc,
374  CmdLineInterface& parser,
375  Visitor* v)
376 : Arg(flag, name, desc, req, true, v),
377  _value( val ),
378  _typeDesc( typeDesc ),
379  _constraint( NULL )
380 {
381  parser.add( this );
382 }
383 
384 template<class T>
385 ValueArg<T>::ValueArg(const std::string& flag,
386  const std::string& name,
387  const std::string& desc,
388  bool req,
389  T val,
390  Constraint<T>* constraint,
391  Visitor* v)
392 : Arg(flag, name, desc, req, true, v),
393  _value( val ),
394  _typeDesc( constraint->shortID() ),
395  _constraint( constraint )
396 { }
397 
398 template<class T>
399 ValueArg<T>::ValueArg(const std::string& flag,
400  const std::string& name,
401  const std::string& desc,
402  bool req,
403  T val,
404  Constraint<T>* constraint,
405  CmdLineInterface& parser,
406  Visitor* v)
407 : Arg(flag, name, desc, req, true, v),
408  _value( val ),
409  _typeDesc( constraint->shortID() ),
410  _constraint( constraint )
411 {
412  parser.add( this );
413 }
414 
415 
416 /**
417  * Implementation of getValue().
418  */
419 template<class T>
421 
422 /**
423  * Implementation of processArg().
424  */
425 template<class T>
426 bool ValueArg<T>::processArg(int *i, std::vector<std::string>& args)
427 {
428  if ( _ignoreable && Arg::ignoreRest() )
429  return false;
430 
431  if ( _hasBlanks( args[*i] ) )
432  return false;
433 
434  std::string flag = args[*i];
435 
436  std::string value = "";
437  trimFlag( flag, value );
438 
439  if ( argMatches( flag ) )
440  {
441  if ( _alreadySet )
442  throw( CmdLineParseException("Argument already set!", toString()) );
443 
444  if ( Arg::delimiter() != ' ' && value == "" )
445  throw( ArgParseException(
446  "Couldn't find delimiter for this argument!",
447  toString() ) );
448 
449  if ( value == "" )
450  {
451  (*i)++;
452  if ( static_cast<unsigned int>(*i) < args.size() )
453  _extractValue( args[*i] );
454  else
455  throw( ArgParseException("Missing a value for this argument!",
456  toString() ) );
457  }
458  else
459  _extractValue( value );
460 
461  _alreadySet = true;
463  return true;
464  }
465  else
466  return false;
467 }
468 
469 /**
470  * Implementation of shortID.
471  */
472 template<class T>
473 std::string ValueArg<T>::shortID(const std::string& ) const
474 {
475  return Arg::shortID( _typeDesc );
476 }
477 
478 /**
479  * Implementation of longID.
480  */
481 template<class T>
482 std::string ValueArg<T>::longID(const std::string& ) const
483 {
484  return Arg::longID( _typeDesc );
485 }
486 
487 template<class T>
488 void ValueArg<T>::_extractValue( const std::string& val )
489 {
491 
492  int err = ve.extractValue(val);
493 
495  throw( ArgParseException("Couldn't read argument value from string '" +
496  val + "'", toString() ) );
497 
499  throw( ArgParseException(
500  "More than one valid value parsed from string '" +
501  val + "'", toString() ) );
502 
503  if ( _constraint != NULL )
504  if ( ! _constraint->check( _value ) )
505  throw( CmdLineParseException( "Value '" + val +
506  "' does not meet constraint: " +
507  _constraint->description(),
508  toString() ) );
509 }
510 
511 } // namespace TCLAP
512 
513 #endif
Constraint< T > * _constraint
A Constraint this Arg must conform to.
Definition: ValueArg.h:182
virtual bool processArg(int *i, std::vector< std::string > &args)
Handles the processing of the argument.
Definition: ValueArg.h:426
int extractValue(const std::string &val)
Method that will attempt to parse the input stream for a value of type std::string.
Definition: ValueArg.h:141
virtual std::string toString() const
Returns a simple string representation of the argument.
Definition: Arg.h:507
std::string _typeDesc
A human readable description of the type to be parsed.
Definition: ValueArg.h:177
virtual std::string shortID(const std::string &val="val") const
Specialization of shortID.
Definition: ValueArg.h:473
STL namespace.
T & _value
Reference to the value where the result of the extraction will be put.
Definition: ValueArg.h:65
Definition: Arg.h:44
A virtual base class that defines the essential data for all arguments.
Definition: Arg.h:51
This class is used to extract a value from an argument.
Definition: ValueArg.h:52
virtual std::string longID(const std::string &val="val") const
Specialization of longID.
Definition: ValueArg.h:482
virtual void add(Arg &a)=0
Adds an argument to the list of arguments to be parsed.
void _checkWithVisitor() const
Performs the special handling described by the Vistitor.
Definition: Arg.h:519
static char delimiter()
The delimiter that separates an argument flag/name from the value.
Definition: Arg.h:189
virtual std::string shortID(const std::string &valueId="val") const
Returns a short ID for the usage.
Definition: Arg.h:410
bool _alreadySet
Indicates whether the argument has been set.
Definition: Arg.h:115
bool _hasBlanks(const std::string &s) const
Checks whether a given string has blank chars, indicating that it is a combined SwitchArg.
Definition: Arg.h:549
T & getValue()
Returns the value of the argument.
Definition: ValueArg.h:420
Thrown from CmdLine when the arguments on the command line are not properly specified, e.g.
Definition: ArgException.h:151
int extractValue(const std::string &val)
Method that will attempt to parse the input stream for a value of type T.
Definition: ValueArg.h:78
virtual void trimFlag(std::string &flag, std::string &value) const
Trims a value off of the flag.
Definition: Arg.h:528
A base class that defines the interface for visitors.
Definition: Visitor.h:39
virtual std::string longID(const std::string &valueId="val") const
Returns a long ID for the usage.
Definition: Arg.h:431
void _extractValue(const std::string &val)
Extracts the value from the string.
Definition: ValueArg.h:488
The basic labeled argument that parses a value.
Definition: ValueArg.h:37
Thrown from within the child Arg classes when it fails to properly parse the argument it has been pas...
Definition: ArgException.h:129
bool _ignoreable
Whether this argument can be ignored, if desired.
Definition: Arg.h:128
ValueExtractor(T &value)
Constructor.
Definition: ValueArg.h:71
ValueArg(const std::string &flag, const std::string &name, const std::string &desc, bool req, T value, const std::string &typeDesc, Visitor *v=NULL)
Labeled ValueArg constructor.
Definition: ValueArg.h:354
virtual bool argMatches(const std::string &s) const
A method that tests whether a string matches this argument.
Definition: Arg.h:498
static bool ignoreRest()
Whether to ignore the rest.
Definition: Arg.h:183
T _value
The value parsed from the command line.
Definition: ValueArg.h:168
The interface that defines the interaction between the Arg and Constraint.
Definition: Constraint.h:46
The base class that manages the command line definition and passes along the parsing to the appropria...



Page generated by Doxygen 1.8.11 for MRPT 1.4.0 SVN:Unversioned directory at Mon May 30 18:20:32 UTC 2016