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



Page generated by Doxygen 1.8.3 for MRPT 0.9.6 SVN: at Fri Feb 15 22:05:02 EST 2013