Main MRPT website > C++ reference for MRPT 1.4.0
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-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_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
35namespace TCLAP {
36
37template<class T> class MultiArg;
38
39namespace 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 */
52template<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 */
117template<>
118class 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 */
155template<class T>
156class 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
321template<class T>
322MultiArg<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{
334}
335
336template<class T>
337MultiArg<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 );
351}
352
353/**
354 *
355 */
356template<class T>
357MultiArg<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{
369}
370
371template<class T>
372MultiArg<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 );
386}
387
388template<class T>
389const std::vector<T>& MultiArg<T>::getValue() { return _values; }
390
391template<class T>
392bool 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;
434 _checkWithVisitor();
435
436 return true;
437 }
438 else
439 return false;
440}
441
442/**
443 *
444 */
445template<class T>
446std::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 */
456template<class T>
457std::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 */
468template<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
483template<class T>
484void 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
506template<class T>
508{
509 bool am = _allowMore;
510 _allowMore = true;
511 return am;
512}
513
514} // namespace TCLAP
515
516#endif
A virtual base class that defines the essential data for all arguments.
Definition: Arg.h:52
bool _acceptsMultipleValues
Definition: Arg.h:136
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 values of type std::string.
Definition: MultiArg.h:141
This class is used to extract a value from an argument.
Definition: MultiArg.h:54
std::vector< T > & _values
Reference to the vector of values where the result of the extraction will be put.
Definition: MultiArg.h:63
ValueExtractor(std::vector< T > &values)
Constructor.
Definition: MultiArg.h:69
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:157
std::string _typeDesc
The description of type T to be used in the usage.
Definition: MultiArg.h:168
void _extractValue(const std::string &val)
Extracts the value from the string.
Definition: MultiArg.h:484
virtual bool processArg(int *i, std::vector< std::string > &args)
Handles the processing of the argument.
Definition: MultiArg.h:392
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
virtual bool isRequired() const
Once we've matched the first value, then the arg is no longer required.
Definition: MultiArg.h:469
std::vector< T > _values
The list of values parsed from the CmdLine.
Definition: MultiArg.h:163
virtual bool allowMore()
Definition: MultiArg.h:507
virtual std::string shortID(const std::string &val="val") const
Returns the a short id string.
Definition: MultiArg.h:446
virtual std::string longID(const std::string &val="val") const
Returns the a long id string.
Definition: MultiArg.h:457
Constraint< T > * _constraint
A list of constraint on this Arg.
Definition: MultiArg.h:173
const std::vector< T > & getValue()
Returns a vector of type T containing the values parsed from the command line.
Definition: MultiArg.h:389
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.5 for MRPT 1.4.0 SVN: at Sun Nov 27 03:17:04 UTC 2022