tclap  1.4.0
ArgGroup.h
Go to the documentation of this file.
1 // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
2 
3 /******************************************************************************
4  *
5  * file: ArgGroup.h
6  *
7  * Copyright (c) 2017 Google LLC.
8  * All rights reserved.
9  *
10  * See the file COPYING in the top directory of this distribution for
11  * more information.
12  *
13  * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
14  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19  * DEALINGS IN THE SOFTWARE.
20  *
21  *****************************************************************************/
22 
23 #ifndef TCLAP_ARG_GROUP_H
24 #define TCLAP_ARG_GROUP_H
25 
26 #include <tclap/Arg.h>
27 #include <tclap/ArgContainer.h>
28 #include <tclap/CmdLineInterface.h>
29 
30 #include <list>
31 #include <string>
32 
33 namespace TCLAP {
34 
41 class ArgGroup : public ArgContainer {
42 public:
43  typedef std::list<Arg *> Container;
44  typedef Container::iterator iterator;
45  typedef Container::const_iterator const_iterator;
46 
47  virtual ~ArgGroup() {}
48 
50  virtual ArgContainer &add(Arg &arg) { return add(&arg); }
51 
53  virtual ArgContainer &add(Arg *arg);
54 
64  virtual bool validate() = 0;
65 
71  virtual bool isRequired() const = 0;
72 
80  virtual bool isExclusive() const = 0;
81 
90  void setParser(CmdLineInterface &parser) {
91  if (_parser) {
92  throw SpecificationException("Arg group can have only one parser");
93  }
94 
95  _parser = &parser;
96  for (iterator it = begin(); it != end(); ++it) {
97  parser.addToArgList(*it);
98  }
99  }
100 
104  virtual bool showAsGroup() const { return true; }
105 
107  const std::string getName() const;
108 
109  iterator begin() { return _args.begin(); }
110  iterator end() { return _args.end(); }
111  const_iterator begin() const { return _args.begin(); }
112  const_iterator end() const { return _args.end(); }
113 
114 protected:
115  // No direct instantiation
116  ArgGroup() : _parser(0), _args() {}
117 
118 private:
119  explicit ArgGroup(const ArgGroup &);
120  ArgGroup &operator=(const ArgGroup &); // no copy
121 
122 protected:
124  Container _args;
125 };
126 
132 class ExclusiveArgGroup : public ArgGroup {
133 public:
134  inline bool validate();
135  bool isExclusive() const { return true; }
136  ArgContainer &add(Arg &arg) { return add(&arg); }
138  if (arg->isRequired()) {
140  "Required arguments are not allowed"
141  " in an exclusive grouping.",
142  arg->longID());
143  }
144 
145  return ArgGroup::add(arg);
146  }
147 
148 protected:
150  explicit ExclusiveArgGroup(CmdLineInterface &parser) { parser.add(*this); }
151 };
152 
156 class EitherOf : public ExclusiveArgGroup {
157 public:
158  EitherOf() {}
159  explicit EitherOf(CmdLineInterface &parser) : ExclusiveArgGroup(parser) {}
160 
161  bool isRequired() const { return false; }
162 };
163 
168 class OneOf : public ExclusiveArgGroup {
169 public:
170  OneOf() {}
171  explicit OneOf(CmdLineInterface &parser) : ExclusiveArgGroup(parser) {}
172 
173  bool isRequired() const { return true; }
174 };
175 
182 class AnyOf : public ArgGroup {
183 public:
184  AnyOf() {}
185  explicit AnyOf(CmdLineInterface &parser) { parser.add(*this); }
186 
187  bool validate() { return false; /* All good */ }
188  bool isExclusive() const { return false; }
189  bool isRequired() const { return false; }
190 };
191 
193  for (iterator it = begin(); it != end(); it++) {
194  if (*arg == **it) {
196  "Argument with same flag/name already exists!", arg->longID());
197  }
198  }
199 
200  _args.push_back(arg);
201  if (_parser) {
202  _parser->addToArgList(arg);
203  }
204 
205  return *this;
206 }
207 
209  Arg *arg = NULL;
210  std::string flag;
211 
212  for (const_iterator it = begin(); it != end(); ++it) {
213  if ((*it)->isSet()) {
214  if (arg != NULL && !(*arg == **it)) {
215  // We found a matching argument, but one was
216  // already found previously.
217  throw CmdLineParseException(
218  "Only one is allowed.",
219  flag + " AND " + (*it)->setBy() + " provided.");
220  }
221 
222  arg = *it;
223  flag = arg->setBy();
224  }
225  }
226 
227  return isRequired() && !arg;
228 }
229 
230 inline const std::string ArgGroup::getName() const {
231  std::string name;
232  std::string sep = "{"; // TODO: this should change for
233  // non-exclusive arg groups
234  for (const_iterator it = begin(); it != end(); ++it) {
235  name += sep + (*it)->getName();
236  sep = " | ";
237  }
238 
239  return name + '}';
240 }
241 
243 inline int CountVisibleArgs(const ArgGroup &g) {
244  int visible = 0;
245  for (ArgGroup::const_iterator it = g.begin(); it != g.end(); ++it) {
246  if ((*it)->visibleInHelp()) {
247  visible++;
248  }
249  }
250 
251  return visible;
252 }
253 
254 } // namespace TCLAP
255 
256 #endif // TCLAP_ARG_GROUP_H
virtual bool isRequired() const =0
Returns true if this argument group is required.
Implements a group of arguments where exactly one must be selected.
Definition: ArgGroup.h:168
bool isExclusive() const
Returns true if this argument group is exclusive.
Definition: ArgGroup.h:188
void setParser(CmdLineInterface &parser)
Used by the parser to connect itself to this arg group.
Definition: ArgGroup.h:90
A virtual base class that defines the essential data for all arguments.
Definition: Arg.h:53
Implements common functionality for exclusive argument groups.
Definition: ArgGroup.h:132
iterator begin()
Definition: ArgGroup.h:109
Thrown from CmdLine when the arguments on the command line are not properly specified, e.g.
Definition: ArgException.h:129
bool isRequired() const
Returns true if this argument group is required.
Definition: ArgGroup.h:189
virtual ArgContainer & add(Arg &a)=0
Adds an argument.
Thrown from Arg and CmdLine when an Arg is improperly specified, e.g.
Definition: ArgException.h:150
virtual std::string longID(const std::string &valueId="val") const
Returns a long ID for the usage.
Definition: Arg.h:498
bool isRequired() const
Returns true if this argument group is required.
Definition: ArgGroup.h:173
Container::const_iterator const_iterator
Definition: ArgGroup.h:45
virtual bool isRequired() const
Indicates whether the argument is required.
Definition: Arg.h:527
virtual void addToArgList(Arg *a)=0
virtual ArgContainer & add(Arg &arg)
Add an argument to this arg group.
Definition: ArgGroup.h:50
Interface that allows adding an Arg to a "container".
Definition: ArgContainer.h:39
OneOf(CmdLineInterface &parser)
Definition: ArgGroup.h:171
ArgContainer & add(Arg *arg)
Add an argument to this arg group.
Definition: ArgGroup.h:137
bool validate()
Validates that the constraints of the ArgGroup are satisfied.
Definition: ArgGroup.h:208
virtual bool isExclusive() const =0
Returns true if this argument group is exclusive.
Container::iterator iterator
Definition: ArgGroup.h:44
ArgContainer & add(Arg &arg)
Add an argument to this arg group.
Definition: ArgGroup.h:136
const_iterator end() const
Definition: ArgGroup.h:112
The base class that manages the command line definition and passes along the parsing to the appropria...
int CountVisibleArgs(const ArgGroup &g)
Definition: ArgGroup.h:243
Implements a group of arguments where at most one can be selected.
Definition: ArgGroup.h:156
Container _args
Definition: ArgGroup.h:124
const_iterator begin() const
Definition: ArgGroup.h:111
virtual bool showAsGroup() const
If arguments in this group should show up as grouped in help.
Definition: ArgGroup.h:104
virtual ~ArgGroup()
Definition: ArgGroup.h:47
bool validate()
Validates that the constraints of the ArgGroup are satisfied.
Definition: ArgGroup.h:187
virtual bool validate()=0
Validates that the constraints of the ArgGroup are satisfied.
Implements a group of arguments where any combination is possible (including all or none)...
Definition: ArgGroup.h:182
ExclusiveArgGroup(CmdLineInterface &parser)
Definition: ArgGroup.h:150
bool isRequired() const
Returns true if this argument group is required.
Definition: ArgGroup.h:161
EitherOf(CmdLineInterface &parser)
Definition: ArgGroup.h:159
CmdLineInterface * _parser
Definition: ArgGroup.h:123
std::list< Arg * > Container
Definition: ArgGroup.h:43
Definition: Arg.h:46
ArgGroup is the base class for implementing groups of arguments that are mutually exclusive (it repla...
Definition: ArgGroup.h:41
bool isExclusive() const
Returns true if this argument group is exclusive.
Definition: ArgGroup.h:135
AnyOf(CmdLineInterface &parser)
Definition: ArgGroup.h:185
iterator end()
Definition: ArgGroup.h:110
const std::string getName() const
Returns the argument group&#39;s name.
Definition: ArgGroup.h:230