Main MRPT website > C++ reference for MRPT 1.5.3
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-2017, 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 std::string longID(const std::string &val="val") const
Specialization of longID.
Definition: ValueArg.h:482
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
void _checkWithVisitor() const
Performs the special handling described by the Vistitor.
Definition: Arg.h:519
std::string _typeDesc
A human readable description of the type to be parsed.
Definition: ValueArg.h:177
virtual std::string shortID(const std::string &valueId="val") const
Returns a short ID for the usage.
Definition: Arg.h:410
T value(details::expression_node< T > *n)
Definition: exprtk.hpp:12104
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
virtual std::string longID(const std::string &valueId="val") const
Returns a long ID for the usage.
Definition: Arg.h:431
virtual bool argMatches(const std::string &s) const
A method that tests whether a string matches this argument.
Definition: Arg.h:498
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 void add(Arg &a)=0
Adds an argument to the list of arguments to be parsed.
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 &val="val") const
Specialization of shortID.
Definition: ValueArg.h:473
bool _alreadySet
Indicates whether the argument has been set.
Definition: Arg.h:115
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
A base class that defines the interface for visitors.
Definition: Visitor.h:39
void _extractValue(const std::string &val)
Extracts the value from the string.
Definition: ValueArg.h:488
virtual void trimFlag(std::string &flag, std::string &value) const
Trims a value off of the flag.
Definition: Arg.h:528
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
virtual std::string toString() const
Returns a simple string representation of the argument.
Definition: Arg.h:507
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
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
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
The base class that manages the command line definition and passes along the parsing to the appropria...



Page generated by Doxygen 1.8.13 for MRPT 1.5.3 at Mon Oct 30 10:27:08 UTC 2017