tclap  1.2.0
MultiArg.h
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * file: MultiArg.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_MULTIPLE_ARGUMENT_H
24 #define TCLAP_MULTIPLE_ARGUMENT_H
25 
26 #include <string>
27 #include <vector>
28 
29 #include <tclap/Arg.h>
30 #include <tclap/Constraint.h>
31 
32 namespace TCLAP {
38 template<class T>
39 class MultiArg : public Arg
40 {
41 public:
42  typedef std::vector<T> container_type;
43  typedef typename container_type::iterator iterator;
44  typedef typename container_type::const_iterator const_iterator;
45 
46 protected:
47 
51  std::vector<T> _values;
52 
56  std::string _typeDesc;
57 
62 
69  void _extractValue( const std::string& val );
70 
74  bool _allowMore;
75 
76 public:
77 
95  MultiArg( const std::string& flag,
96  const std::string& name,
97  const std::string& desc,
98  bool req,
99  const std::string& typeDesc,
100  Visitor* v = NULL);
101 
120  MultiArg( const std::string& flag,
121  const std::string& name,
122  const std::string& desc,
123  bool req,
124  const std::string& typeDesc,
125  CmdLineInterface& parser,
126  Visitor* v = NULL );
127 
143  MultiArg( const std::string& flag,
144  const std::string& name,
145  const std::string& desc,
146  bool req,
147  Constraint<T>* constraint,
148  Visitor* v = NULL );
149 
166  MultiArg( const std::string& flag,
167  const std::string& name,
168  const std::string& desc,
169  bool req,
170  Constraint<T>* constraint,
171  CmdLineInterface& parser,
172  Visitor* v = NULL );
173 
182  virtual bool processArg(int* i, std::vector<std::string>& args);
183 
188  const std::vector<T>& getValue();
189 
194  const_iterator begin() const { return _values.begin(); }
195 
200  const_iterator end() const { return _values.end(); }
201 
206  virtual std::string shortID(const std::string& val="val") const;
207 
212  virtual std::string longID(const std::string& val="val") const;
213 
218  virtual bool isRequired() const;
219 
220  virtual bool allowMore();
221 
222  virtual void reset();
223 
224 };
225 
226 template<class T>
227 MultiArg<T>::MultiArg(const std::string& flag,
228  const std::string& name,
229  const std::string& desc,
230  bool req,
231  const std::string& typeDesc,
232  Visitor* v)
233 : Arg( flag, name, desc, req, true, v ),
234  _typeDesc( typeDesc ),
235  _constraint( NULL ),
236  _allowMore(false)
237 {
238  _acceptsMultipleValues = true;
239 }
240 
241 template<class T>
242 MultiArg<T>::MultiArg(const std::string& flag,
243  const std::string& name,
244  const std::string& desc,
245  bool req,
246  const std::string& typeDesc,
247  CmdLineInterface& parser,
248  Visitor* v)
249 : Arg( flag, name, desc, req, true, v ),
250  _typeDesc( typeDesc ),
251  _constraint( NULL ),
252  _allowMore(false)
253 {
254  parser.add( this );
255  _acceptsMultipleValues = true;
256 }
257 
261 template<class T>
262 MultiArg<T>::MultiArg(const std::string& flag,
263  const std::string& name,
264  const std::string& desc,
265  bool req,
266  Constraint<T>* constraint,
267  Visitor* v)
268 : Arg( flag, name, desc, req, true, v ),
269  _typeDesc( constraint->shortID() ),
270  _constraint( constraint ),
271  _allowMore(false)
272 {
273  _acceptsMultipleValues = true;
274 }
275 
276 template<class T>
277 MultiArg<T>::MultiArg(const std::string& flag,
278  const std::string& name,
279  const std::string& desc,
280  bool req,
281  Constraint<T>* constraint,
282  CmdLineInterface& parser,
283  Visitor* v)
284 : Arg( flag, name, desc, req, true, v ),
285  _typeDesc( constraint->shortID() ),
286  _constraint( constraint ),
287  _allowMore(false)
288 {
289  parser.add( this );
290  _acceptsMultipleValues = true;
291 }
292 
293 template<class T>
294 const std::vector<T>& MultiArg<T>::getValue() { return _values; }
295 
296 template<class T>
297 bool MultiArg<T>::processArg(int *i, std::vector<std::string>& args)
298 {
299  if ( _ignoreable && Arg::ignoreRest() )
300  return false;
301 
302  if ( _hasBlanks( args[*i] ) )
303  return false;
304 
305  std::string flag = args[*i];
306  std::string value = "";
307 
308  trimFlag( flag, value );
309 
310  if ( argMatches( flag ) )
311  {
312  if ( Arg::delimiter() != ' ' && value == "" )
313  throw( ArgParseException(
314  "Couldn't find delimiter for this argument!",
315  toString() ) );
316 
317  // always take the first one, regardless of start string
318  if ( value == "" )
319  {
320  (*i)++;
321  if ( static_cast<unsigned int>(*i) < args.size() )
322  _extractValue( args[*i] );
323  else
324  throw( ArgParseException("Missing a value for this argument!",
325  toString() ) );
326  }
327  else
328  _extractValue( value );
329 
330  /*
331  // continuing taking the args until we hit one with a start string
332  while ( (unsigned int)(*i)+1 < args.size() &&
333  args[(*i)+1].find_first_of( Arg::flagStartString() ) != 0 &&
334  args[(*i)+1].find_first_of( Arg::nameStartString() ) != 0 )
335  _extractValue( args[++(*i)] );
336  */
337 
338  _alreadySet = true;
339  _checkWithVisitor();
340 
341  return true;
342  }
343  else
344  return false;
345 }
346 
350 template<class T>
351 std::string MultiArg<T>::shortID(const std::string& val) const
352 {
353  static_cast<void>(val); // Ignore input, don't warn
354  return Arg::shortID(_typeDesc) + " ... ";
355 }
356 
360 template<class T>
361 std::string MultiArg<T>::longID(const std::string& val) const
362 {
363  static_cast<void>(val); // Ignore input, don't warn
364  return Arg::longID(_typeDesc) + " (accepted multiple times)";
365 }
366 
371 template<class T>
373 {
374  if ( _required )
375  {
376  if ( _values.size() > 1 )
377  return false;
378  else
379  return true;
380  }
381  else
382  return false;
383 
384 }
385 
386 template<class T>
387 void MultiArg<T>::_extractValue( const std::string& val )
388 {
389  try {
390  T tmp;
391  ExtractValue(tmp, val, typename ArgTraits<T>::ValueCategory());
392  _values.push_back(tmp);
393  } catch( ArgParseException &e) {
394  throw ArgParseException(e.error(), toString());
395  }
396 
397  if ( _constraint != NULL )
398  if ( ! _constraint->check( _values.back() ) )
399  throw( CmdLineParseException( "Value '" + val +
400  "' does not meet constraint: " +
401  _constraint->description(),
402  toString() ) );
403 }
404 
405 template<class T>
407 {
408  bool am = _allowMore;
409  _allowMore = true;
410  return am;
411 }
412 
413 template<class T>
415 {
416  Arg::reset();
417  _values.clear();
418 }
419 
420 } // namespace TCLAP
421 
422 #endif