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...
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,...
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.7 for MRPT 1.4.0 SVN: at Tue Jun 13 14:27:49 UTC 2023