SPH
ArgsParser.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "io/Logger.h"
4 #include "objects/Exceptions.h"
9 #include "system/Settings.h"
10 
12 
13 enum class ArgEnum {
14  NONE,
15  BOOL,
16  INT,
17  FLOAT,
18  STRING,
19 };
20 
21 
23 class ArgError : public Exception {
24 public:
25  explicit ArgError(const std::string& message)
26  : Exception(message) {}
27 };
28 
32 class HelpException : public Exception {
33 public:
34  explicit HelpException(const std::string& message)
35  : Exception(message) {}
36 };
37 
39 struct ArgDesc {
41  std::string shortName;
42 
44  std::string longName;
45 
48 
50  std::string desc;
51 
53  Function<void()> callback = nullptr;
54 
56  bool matches(const std::string& name) {
57  return (name == "-" + shortName) || (name == "--" + longName);
58  }
59 };
60 
62 class ArgParser {
63 private:
65 
67  Array<ArgDesc> descs;
68 
71 
72 public:
77  explicit ArgParser(ArrayView<const ArgDesc> args);
78 
84  void parse(const int argc, char** argv);
85 
89  void printHelp(ILogger& logger);
90 
94  template <typename TValue>
95  TValue getArg(const std::string& name) const {
96  throwIfUnknownArg(name);
97  Optional<const ArgValue&> value = params.tryGet(name);
98  if (value && value->has<TValue>()) {
99  return value->get<TValue>();
100  } else {
101  const std::string message = value ? "Invalid type of argument -" : "Missing argument -" + name;
102  throw ArgError(message);
103  }
104  }
105 
109  template <typename TValue>
110  Optional<TValue> tryGetArg(const std::string& name) const {
111  throwIfUnknownArg(name);
112  Optional<const ArgValue&> value = params.tryGet(name);
113  if (value) {
114  if (!value->has<TValue>()) {
115  throw ArgError("Invalid type");
116  }
117  return value->get<TValue>();
118  } else {
119  return NOTHING;
120  }
121  }
122 
133  template <typename TEnum, typename TConvertor>
134  bool tryStore(Settings<TEnum>& settings, const std::string& name, const TEnum idx, TConvertor&& conv) {
135  throwIfUnknownArg(name);
136  auto value = params.tryGet(name);
137  if (value) {
138  // special handling of floats - convert units
139  if (value->has<Float>()) {
140  settings.set(idx, conv(value->get<Float>()));
141  } else {
142  forValue(value.value(), [&settings, idx](auto& value) { settings.set(idx, value); });
143  }
144  return true;
145  }
146  return false;
147  }
148 
152  template <typename TEnum>
153  bool tryStore(Settings<TEnum>& settings, const std::string& name, const TEnum idx) {
154  return tryStore(settings, name, idx, [](Float value) { return value; });
155  }
156 
162  template <typename TFunctor>
163  void forEach(const TFunctor& functor) {
164  for (auto& e : params) {
165  forValue(e.value, [&e, &functor](auto& value) { functor(e.key, value); });
166  }
167  }
168 
170  Size size() const {
171  return params.size();
172  }
173 
175  bool empty() const {
176  return params.empty();
177  }
178 
179 private:
180  void parseValuelessArg(const ArgDesc& desc);
181 
182  void parseValueArg(const ArgDesc& desc, const std::string& value);
183 
184  template <typename TValue>
185  void insertArg(const std::string& name, const std::string& textValue);
186 
187  void throwIfUnknownArg(const std::string& name) const;
188 };
189 
190 
ArgEnum
Definition: ArgsParser.h:13
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
@ NONE
No collision took place.
Key-value associative container implemented as a sorted array.
Generic wrappers of lambdas, functors and other callables.
uint32_t Size
Integral type used to index arrays (by default).
Definition: Globals.h:16
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
Definition: Globals.h:13
Logging routines of the run.
#define NAMESPACE_SPH_END
Definition: Object.h:12
const NothingType NOTHING
Definition: Optional.h:16
Object capable of storing values of different types.
decltype(auto) INLINE forValue(Variant< TArgs... > &variant, TFunctor &&functor)
Definition: Variant.h:428
Exception thrown if the arguments are invalid.
Definition: ArgsParser.h:23
ArgError(const std::string &message)
Definition: ArgsParser.h:25
Provides functions for parsing command-line arguments.
Definition: ArgsParser.h:62
bool empty() const
Returns true if no arguments have been parsed.
Definition: ArgsParser.h:175
bool tryStore(Settings< TEnum > &settings, const std::string &name, const TEnum idx, TConvertor &&conv)
Stores the value of given argument into an instance of Settings.
Definition: ArgsParser.h:134
void parse(const int argc, char **argv)
Parses the input arguments and stored the parsed values.
Definition: ArgsParser.cpp:16
TValue getArg(const std::string &name) const
Returns the value of an argument, given its short name (without the dash).
Definition: ArgsParser.h:95
Optional< TValue > tryGetArg(const std::string &name) const
Returns the value of an argument or NOTHING if the argument was not parsed.
Definition: ArgsParser.h:110
void printHelp(ILogger &logger)
Prints the help information into given logger.
Definition: ArgsParser.cpp:51
bool tryStore(Settings< TEnum > &settings, const std::string &name, const TEnum idx)
Stores the value of given argument into an instance of Settings.
Definition: ArgsParser.h:153
Size size() const
Returns the number of parsed arguments.
Definition: ArgsParser.h:170
ArgParser(ArrayView< const ArgDesc > args)
Creates a parser, given a set of parameter descriptors.
Definition: ArgsParser.cpp:6
void forEach(const TFunctor &functor)
Enumerates all parsed arguments and executes a generic functor with parsed values.
Definition: ArgsParser.h:163
Object providing safe access to continuous memory of data.
Definition: ArrayView.h:17
Generic exception.
Definition: Exceptions.h:10
Container of key-value pairs.
Definition: FlatMap.h:19
INLINE Size empty() const
Returns true if the map contains no elements, false otherwise.
Definition: FlatMap.h:150
INLINE Optional< TValue & > tryGet(const TKey &key)
Returns a reference to the value matching the given key, or NOTHING if no such value exists.
Definition: FlatMap.h:118
INLINE Size size() const
Returns the number of elements in the map.
Definition: FlatMap.h:145
Exception thrown when used passes -h or –help parameter.
Definition: ArgsParser.h:32
HelpException(const std::string &message)
Definition: ArgsParser.h:34
Interface providing generic (text, human readable) output of the program.
Definition: Logger.h:22
Wrapper of type value of which may or may not be present.
Definition: Optional.h:23
Generic object containing various settings and parameters of the run.
Definition: Settings.h:108
Settings & set(const TEnum idx, TValue &&value, std::enable_if_t<!std::is_enum< std::decay_t< TValue >>::value, int >=0)
Saves a value into the settings.
Definition: Settings.h:226
Variant, an implementation of type-safe union, similar to std::variant or boost::variant.
Definition: Variant.h:171
Generic storage and input/output routines of settings.
Descriptor of a command-line argument.
Definition: ArgsParser.h:39
std::string shortName
Short name, prefixed by single dash (e.g. -h)
Definition: ArgsParser.h:41
std::string longName
Long name, prefixed by double-dash (e.g. –help)
Definition: ArgsParser.h:44
bool matches(const std::string &name)
Checks if the descriptor matches given argument.
Definition: ArgsParser.h:56
std::string desc
Parameter description, printed in help.
Definition: ArgsParser.h:50
Function< void()> callback
Generic callback executed when the parameter is parsed.
Definition: ArgsParser.h:53
ArgEnum type
Type of the parameter.
Definition: ArgsParser.h:47