Main MRPT website > C++ reference for MRPT 1.5.3
MultiArg.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_MULTIPLE_ARGUMENT_H
12 #define TCLAP_MULTIPLE_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 MultiArg;
38 
39 namespace MULTI_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>
54 {
55  friend class MultiArg<T>;
56 
57  private:
58 
59  /**
60  * Reference to the vector of values where the result of the
61  * extraction will be put.
62  */
63  std::vector<T> &_values;
64 
65  /**
66  * Constructor.
67  * \param values - Where the values extracted will be put.
68  */
69  ValueExtractor(std::vector<T> &values) : _values(values) {}
70 
71  /**
72  * Method that will attempt to parse the input stream for values
73  * of type T.
74  * \param val - Where the values parsed will be put.
75  */
76  int extractValue( const std::string& val )
77  {
78  T temp;
79 
80 #if defined(HAVE_SSTREAM)
81  std::istringstream is(val);
82 #elif defined(HAVE_STRSTREAM)
83  std::istrstream is(val.c_str());
84 #else
85 #error "Need a stringstream (sstream or strstream) to compile!"
86 #endif
87 
88  int valuesRead = 0;
89 
90  while ( is.good() )
91  {
92  if ( is.peek() != EOF )
93  is >> temp;
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  _values.push_back(temp);
107 
108  return 0;
109  }
110 };
111 
112 /**
113  * Specialization for string. This is necessary because istringstream
114  * operator>> is not able to ignore spaces... meaning -x "X Y" will only
115  * read 'X'... and thus the specialization.
116  */
117 template<>
118 class ValueExtractor<std::string>
119 {
120  friend class MultiArg<std::string>;
121 
122  private:
123 
124  /**
125  * Reference to the vector of strings where the result of the
126  * extraction will be put.
127  */
128  std::vector<std::string> &_values;
129 
130  /**
131  * Constructor.
132  * \param values - Where the strings extracted will be put.
133  */
134  ValueExtractor(std::vector<std::string> &values) : _values(values) {}
135 
136  /**
137  * Method that will attempt to parse the input stream for values
138  * of type std::string.
139  * \param val - Where the values parsed will be put.
140  */
141  int extractValue( const std::string& val )
142  {
143  _values.push_back( val );
144  return 0;
145  }
146 };
147 
148 } //namespace MULTI_ARG_HELPER
149 
150 /**
151  * An argument that allows multiple values of type T to be specified. Very
152  * similar to a ValueArg, except a vector of values will be returned
153  * instead of just one.
154  */
155 template<class T>
156 class MultiArg : public Arg
157 {
158  protected:
159 
160  /**
161  * The list of values parsed from the CmdLine.
162  */
163  std::vector<T> _values;
164 
165  /**
166  * The description of type T to be used in the usage.
167  */
168  std::string _typeDesc;
169 
170  /**
171  * A list of constraint on this Arg.
172  */
174 
175  /**
176  * Extracts the value from the string.
177  * Attempts to parse string as type T, if this fails an exception
178  * is thrown.
179  * \param val - The string to be read.
180  */
181  void _extractValue( const std::string& val );
182 
184 
185  public:
186 
187  /**
188  * Constructor.
189  * \param flag - The one character flag that identifies this
190  * argument on the command line.
191  * \param name - A one word name for the argument. Can be
192  * used as a long flag on the command line.
193  * \param desc - A description of what the argument is for or
194  * does.
195  * \param req - Whether the argument is required on the command
196  * line.
197  * \param typeDesc - A short, human readable description of the
198  * type that this object expects. This is used in the generation
199  * of the USAGE statement. The goal is to be helpful to the end user
200  * of the program.
201  * \param v - An optional visitor. You probably should not
202  * use this unless you have a very good reason.
203  */
204  MultiArg( const std::string& flag,
205  const std::string& name,
206  const std::string& desc,
207  bool req,
208  const std::string& typeDesc,
209  Visitor* v = NULL);
210 
211  /**
212  * Constructor.
213  * \param flag - The one character flag that identifies this
214  * argument on the command line.
215  * \param name - A one word name for the argument. Can be
216  * used as a long flag on the command line.
217  * \param desc - A description of what the argument is for or
218  * does.
219  * \param req - Whether the argument is required on the command
220  * line.
221  * \param typeDesc - A short, human readable description of the
222  * type that this object expects. This is used in the generation
223  * of the USAGE statement. The goal is to be helpful to the end user
224  * of the program.
225  * \param parser - A CmdLine parser object to add this Arg to
226  * \param v - An optional visitor. You probably should not
227  * use this unless you have a very good reason.
228  */
229  MultiArg( const std::string& flag,
230  const std::string& name,
231  const std::string& desc,
232  bool req,
233  const std::string& typeDesc,
234  CmdLineInterface& parser,
235  Visitor* v = NULL );
236 
237  /**
238  * Constructor.
239  * \param flag - The one character flag that identifies this
240  * argument on the command line.
241  * \param name - A one word name for the argument. Can be
242  * used as a long flag on the command line.
243  * \param desc - A description of what the argument is for or
244  * does.
245  * \param req - Whether the argument is required on the command
246  * line.
247  * \param constraint - A pointer to a Constraint object used
248  * to constrain this Arg.
249  * \param v - An optional visitor. You probably should not
250  * use this unless you have a very good reason.
251  */
252  MultiArg( const std::string& flag,
253  const std::string& name,
254  const std::string& desc,
255  bool req,
256  Constraint<T>* constraint,
257  Visitor* v = NULL );
258 
259  /**
260  * Constructor.
261  * \param flag - The one character flag that identifies this
262  * argument on the command line.
263  * \param name - A one word name for the argument. Can be
264  * used as a long flag on the command line.
265  * \param desc - A description of what the argument is for or
266  * does.
267  * \param req - Whether the argument is required on the command
268  * line.
269  * \param constraint - A pointer to a Constraint object used
270  * to constrain this Arg.
271  * \param parser - A CmdLine parser object to add this Arg to
272  * \param v - An optional visitor. You probably should not
273  * use this unless you have a very good reason.
274  */
275  MultiArg( const std::string& flag,
276  const std::string& name,
277  const std::string& desc,
278  bool req,
279  Constraint<T>* constraint,
280  CmdLineInterface& parser,
281  Visitor* v = NULL );
282 
283  /**
284  * Handles the processing of the argument.
285  * This re-implements the Arg version of this method to set the
286  * _value of the argument appropriately. It knows the difference
287  * between labeled and unlabeled.
288  * \param i - Pointer the the current argument in the list.
289  * \param args - Mutable list of strings. Passed from main().
290  */
291  virtual bool processArg(int* i, std::vector<std::string>& args);
292 
293  /**
294  * Returns a vector of type T containing the values parsed from
295  * the command line.
296  */
297  const std::vector<T>& getValue();
298 
299  /**
300  * Returns the a short id string. Used in the usage.
301  * \param val - value to be used.
302  */
303  virtual std::string shortID(const std::string& val="val") const;
304 
305  /**
306  * Returns the a long id string. Used in the usage.
307  * \param val - value to be used.
308  */
309  virtual std::string longID(const std::string& val="val") const;
310 
311  /**
312  * Once we've matched the first value, then the arg is no longer
313  * required.
314  */
315  virtual bool isRequired() const;
316 
317  virtual bool allowMore();
318 
319 };
320 
321 template<class T>
322 MultiArg<T>::MultiArg(const std::string& flag,
323  const std::string& name,
324  const std::string& desc,
325  bool req,
326  const std::string& typeDesc,
327  Visitor* v)
328 : Arg( flag, name, desc, req, true, v ),
329  _typeDesc( typeDesc ),
330  _constraint( NULL ),
331  _allowMore(false)
332 {
333  _acceptsMultipleValues = true;
334 }
335 
336 template<class T>
337 MultiArg<T>::MultiArg(const std::string& flag,
338  const std::string& name,
339  const std::string& desc,
340  bool req,
341  const std::string& typeDesc,
342  CmdLineInterface& parser,
343  Visitor* v)
344 : Arg( flag, name, desc, req, true, v ),
345  _typeDesc( typeDesc ),
346  _constraint( NULL ),
347  _allowMore(false)
348 {
349  parser.add( this );
350  _acceptsMultipleValues = true;
351 }
352 
353 /**
354  *
355  */
356 template<class T>
357 MultiArg<T>::MultiArg(const std::string& flag,
358  const std::string& name,
359  const std::string& desc,
360  bool req,
361  Constraint<T>* constraint,
362  Visitor* v)
363 : Arg( flag, name, desc, req, true, v ),
364  _typeDesc( constraint->shortID() ),
365  _constraint( constraint ),
366  _allowMore(false)
367 {
368  _acceptsMultipleValues = true;
369 }
370 
371 template<class T>
372 MultiArg<T>::MultiArg(const std::string& flag,
373  const std::string& name,
374  const std::string& desc,
375  bool req,
376  Constraint<T>* constraint,
377  CmdLineInterface& parser,
378  Visitor* v)
379 : Arg( flag, name, desc, req, true, v ),
380  _typeDesc( constraint->shortID() ),
381  _constraint( constraint ),
382  _allowMore(false)
383 {
384  parser.add( this );
385  _acceptsMultipleValues = true;
386 }
387 
388 template<class T>
389 const std::vector<T>& MultiArg<T>::getValue() { return _values; }
390 
391 template<class T>
392 bool MultiArg<T>::processArg(int *i, std::vector<std::string>& args)
393 {
394  if ( _ignoreable && Arg::ignoreRest() )
395  return false;
396 
397  if ( _hasBlanks( args[*i] ) )
398  return false;
399 
400  std::string flag = args[*i];
401  std::string value = "";
402 
403  trimFlag( flag, value );
404 
405  if ( argMatches( flag ) )
406  {
407  if ( Arg::delimiter() != ' ' && value == "" )
408  throw( ArgParseException(
409  "Couldn't find delimiter for this argument!",
410  toString() ) );
411 
412  // always take the first one, regardless of start string
413  if ( value == "" )
414  {
415  (*i)++;
416  if ( static_cast<unsigned int>(*i) < args.size() )
417  _extractValue( args[*i] );
418  else
419  throw( ArgParseException("Missing a value for this argument!",
420  toString() ) );
421  }
422  else
423  _extractValue( value );
424 
425  /*
426  // continuing taking the args until we hit one with a start string
427  while ( (unsigned int)(*i)+1 < args.size() &&
428  args[(*i)+1].find_first_of( Arg::flagStartString() ) != 0 &&
429  args[(*i)+1].find_first_of( Arg::nameStartString() ) != 0 )
430  _extractValue( args[++(*i)] );
431  */
432 
433  _alreadySet = true;
435 
436  return true;
437  }
438  else
439  return false;
440 }
441 
442 /**
443  *
444  */
445 template<class T>
446 std::string MultiArg<T>::shortID(const std::string& val) const
447 {
448  std::string id = Arg::shortID(_typeDesc) + " ... ";
449 
450  return id;
451 }
452 
453 /**
454  *
455  */
456 template<class T>
457 std::string MultiArg<T>::longID(const std::string& val) const
458 {
459  std::string id = Arg::longID(_typeDesc) + " (accepted multiple times)";
460 
461  return id;
462 }
463 
464 /**
465  * Once we've matched the first value, then the arg is no longer
466  * required.
467  */
468 template<class T>
470 {
471  if ( _required )
472  {
473  if ( _values.size() > 1 )
474  return false;
475  else
476  return true;
477  }
478  else
479  return false;
480 
481 }
482 
483 template<class T>
484 void MultiArg<T>::_extractValue( const std::string& val )
485 {
487 
488  int err = ve.extractValue(val);
489 
491  throw( ArgParseException("Couldn't read argument value "
492  "from string '" + val + "'", toString() ) );
493 
495  throw( ArgParseException("More than one valid value "
496  "parsed from string '" + val + "'",
497  toString() ) );
498  if ( _constraint != NULL )
499  if ( ! _constraint->check( _values.back() ) )
500  throw( CmdLineParseException( "Value '" + val +
501  "' does not meet constraint: " +
502  _constraint->description(),
503  toString() ) );
504 }
505 
506 template<class T>
508 {
509  bool am = _allowMore;
510  _allowMore = true;
511  return am;
512 }
513 
514 } // namespace TCLAP
515 
516 #endif
bool _acceptsMultipleValues
Definition: Arg.h:136
MultiArg(const std::string &flag, const std::string &name, const std::string &desc, bool req, const std::string &typeDesc, Visitor *v=NULL)
Constructor.
Definition: MultiArg.h:322
This class is used to extract a value from an argument.
Definition: MultiArg.h:53
void _checkWithVisitor() const
Performs the special handling described by the Vistitor.
Definition: Arg.h:519
virtual bool allowMore()
Definition: MultiArg.h:507
int extractValue(const std::string &val)
Method that will attempt to parse the input stream for values of type T.
Definition: MultiArg.h:76
An argument that allows multiple values of type T to be specified.
Definition: MultiArg.h:37
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.
std::vector< T > & _values
Reference to the vector of values where the result of the extraction will be put. ...
Definition: MultiArg.h:63
const std::vector< T > & getValue()
Returns a vector of type T containing the values parsed from the command line.
Definition: MultiArg.h:389
std::vector< T > _values
The list of values parsed from the CmdLine.
Definition: MultiArg.h:163
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
virtual void add(Arg &a)=0
Adds an argument to the list of arguments to be parsed.
virtual bool processArg(int *i, std::vector< std::string > &args)
Handles the processing of the argument.
Definition: MultiArg.h:392
virtual bool isRequired() const
Once we&#39;ve matched the first value, then the arg is no longer required.
Definition: MultiArg.h:469
static char delimiter()
The delimiter that separates an argument flag/name from the value.
Definition: Arg.h:189
int extractValue(const std::string &val)
Method that will attempt to parse the input stream for values of type std::string.
Definition: MultiArg.h:141
bool _alreadySet
Indicates whether the argument has been set.
Definition: Arg.h:115
Thrown from CmdLine when the arguments on the command line are not properly specified, e.g.
Definition: ArgException.h:151
ValueExtractor(std::vector< T > &values)
Constructor.
Definition: MultiArg.h:69
A base class that defines the interface for visitors.
Definition: Visitor.h:39
virtual std::string longID(const std::string &val="val") const
Returns the a long id string.
Definition: MultiArg.h:457
std::string _typeDesc
The description of type T to be used in the usage.
Definition: MultiArg.h:168
virtual void trimFlag(std::string &flag, std::string &value) const
Trims a value off of the flag.
Definition: Arg.h:528
virtual std::string shortID(const std::string &val="val") const
Returns the a short id string.
Definition: MultiArg.h:446
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
Constraint< T > * _constraint
A list of constraint on this Arg.
Definition: MultiArg.h:173
void _extractValue(const std::string &val)
Extracts the value from the string.
Definition: MultiArg.h:484
static bool ignoreRest()
Whether to ignore the rest.
Definition: Arg.h:183
bool _required
Indicating whether the argument is required.
Definition: Arg.h:95
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 Tue Aug 22 01:03:35 UTC 2017