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
35namespace TCLAP {
36
37template<class T> class ValueArg;
38
39namespace 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 */
52template<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 */
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 */
115template<> 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 */
158template<class T>
159class 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 */
353template<class T>
354ValueArg<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
367template<class T>
368ValueArg<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
384template<class T>
385ValueArg<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
398template<class T>
399ValueArg<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 */
419template<class T>
420T& ValueArg<T>::getValue() { return _value; }
421
422/**
423 * Implementation of processArg().
424 */
425template<class T>
426bool 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;
462 _checkWithVisitor();
463 return true;
464 }
465 else
466 return false;
467}
468
469/**
470 * Implementation of shortID.
471 */
472template<class T>
473std::string ValueArg<T>::shortID(const std::string& ) const
474{
475 return Arg::shortID( _typeDesc );
476}
477
478/**
479 * Implementation of longID.
480 */
481template<class T>
482std::string ValueArg<T>::longID(const std::string& ) const
483{
484 return Arg::longID( _typeDesc );
485}
486
487template<class T>
488void 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
A virtual base class that defines the essential data for all arguments.
Definition: Arg.h:52
virtual std::string longID(const std::string &valueId="val") const
Returns a long ID for the usage.
Definition: Arg.h:431
static bool ignoreRest()
Whether to ignore the rest.
Definition: Arg.h:183
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
Thrown from within the child Arg classes when it fails to properly parse the argument it has been pas...
Definition: ArgException.h:130
The base class that manages the command line definition and passes along the parsing to the appropria...
virtual void add(Arg &a)=0
Adds an argument to the list of arguments to be parsed.
Thrown from CmdLine when the arguments on the command line are not properly specified,...
Definition: ArgException.h:152
The interface that defines the interaction between the Arg and Constraint.
Definition: Constraint.h:47
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
This class is used to extract a value from an argument.
Definition: ValueArg.h:53
ValueExtractor(T &value)
Constructor.
Definition: ValueArg.h:71
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
T & _value
Reference to the value where the result of the extraction will be put.
Definition: ValueArg.h:65
The basic labeled argument that parses a value.
Definition: ValueArg.h:160
virtual std::string longID(const std::string &val="val") const
Specialization of longID.
Definition: ValueArg.h:482
T _value
The value parsed from the command line.
Definition: ValueArg.h:168
T & getValue()
Returns the value of the argument.
Definition: ValueArg.h:420
virtual bool processArg(int *i, std::vector< std::string > &args)
Handles the processing of the argument.
Definition: ValueArg.h:426
std::string _typeDesc
A human readable description of the type to be parsed.
Definition: ValueArg.h:177
Constraint< T > * _constraint
A Constraint this Arg must conform to.
Definition: ValueArg.h:182
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
void _extractValue(const std::string &val)
Extracts the value from the string.
Definition: ValueArg.h:488
virtual std::string shortID(const std::string &val="val") const
Specialization of shortID.
Definition: ValueArg.h:473
A base class that defines the interface for visitors.
Definition: Visitor.h:40
Definition: Arg.h:44
STL namespace.



Page generated by Doxygen 1.9.6 for MRPT 1.4.0 SVN: at Fri Jan 20 00:13:14 UTC 2023