67 explicit cmd_base(
const std::string& name,
68 const std::string& alternative,
69 const std::string& description,
78 std::string alternative;
79 std::string description;
82 std::vector<std::string> arguments;
86 virtual auto print_value()
const -> std::string = 0;
87 virtual auto parse(std::ostream& output, std::ostream& error) ->
bool = 0;
89 auto is(
const std::string& given)
const -> bool;
93 struct argument_count_checker
95 static constexpr bool variadic =
false;
101 static constexpr bool variadic =
false;
105 struct argument_count_checker<
std::vector<T>>
107 static constexpr bool variadic =
true;
111 class cmd_function final :
public cmd_base
114 explicit cmd_function(
const std::string& name,
115 const std::string& alternative,
116 const std::string& description,
119 : cmd_base(
name, alternative, description, required, dominant, argument_count_checker<T>::variadic)
123 auto parse(std::ostream& output, std::ostream& error) ->
bool override
128 value = callback(args);
137 auto print_value()
const -> std::string
override
147 class cmd_argument final :
public cmd_base
150 explicit cmd_argument(
const std::string& name,
151 const std::string& alternative,
152 const std::string& description,
155 : cmd_base(
name, alternative, description, required, dominant, argument_count_checker<T>::variadic)
159 auto parse(std::ostream& , std::ostream& ) ->
bool override
163 value = parser::parse(arguments, value);
172 auto print_value()
const -> std::string
override
174 return stringify(value);
180 static auto parse(
const std::vector<std::string>& elements,
const int& ,
int numberBase = 0) -> int;
182 static auto parse(
const std::vector<std::string>& elements,
const bool& defval) -> bool;
184 static auto parse(
const std::vector<std::string>& elements,
const double& ) -> double;
186 static auto parse(
const std::vector<std::string>& elements,
const float& ) -> float;
188 static auto parse(
const std::vector<std::string>& elements,
const long double& ) ->
long double;
190 static auto parse(
const std::vector<std::string>& elements,
const unsigned int& ,
int numberBase = 0)
193 static auto parse(
const std::vector<std::string>& elements,
const unsigned long& ,
int numberBase = 0)
196 static auto parse(
const std::vector<std::string>& elements,
const long& ) -> long;
198 static auto parse(
const std::vector<std::string>& elements,
const std::string& ) -> std::string;
201 static auto parse(
const std::vector<std::string>& elements,
const std::vector<T>& ) -> std::vector<T>
203 const T defval = T();
204 std::vector<T> values{};
205 std::vector<std::string> buffer(1);
207 for(
const auto& element : elements)
210 values.push_back(parse(buffer, defval));
217 static auto parse(
const std::vector<std::string>& elements,
const numeric_base<T>& wrapper) -> T
219 return parse(elements, wrapper.
value, 0);
228 template<
typename T,
int base>
229 static auto parse(
const std::vector<std::string>& elements,
const numeric_base<T, base>& wrapper) -> T
231 return parse(elements, wrapper.
value, wrapper.
base);
235 static auto stringify(
const T& value) -> std::string
237 return std::to_string(value);
240 template<
class T,
int base>
243 return std::to_string(wrapper.
value);
247 static auto stringify(
const std::vector<T>& values) -> std::string
249 std::stringstream ss{};
252 for(
const auto& value : values)
254 ss << stringify(value) <<
" ";
261 static auto stringify(
const std::string& str) -> std::string;
264 explicit parser(
int argc,
const char** argv);
266 explicit parser(
int argc,
char** argv);
288 auto command = std::make_unique<cmd_argument<T>>(
"",
"", description, is_required,
false);
289 commands_.emplace_back(
detail::get_id<cmd_argument<T>>(), std::move(command));
294 const std::string& alternative,
295 const std::string& description =
"",
296 bool dominant =
false)
298 auto command = std::make_unique<cmd_argument<T>>(
name, alternative, description,
true, dominant);
299 commands_.emplace_back(
detail::get_id<cmd_argument<T>>(), std::move(command));
304 const std::string& alternative,
306 const std::string& description =
"",
307 bool dominant =
false)
309 auto command = std::make_unique<cmd_argument<T>>(
name, alternative, description,
false, dominant);
310 command->value = defaultValue;
311 commands_.emplace_back(
detail::get_id<cmd_argument<T>>(), std::move(command));
316 const std::string& alternative,
318 const std::string& description =
"",
319 bool dominant =
false)
321 auto command = std::make_unique<cmd_function<T>>(
name, alternative, description,
false, dominant);
322 command->callback = callback;
323 commands_.emplace_back(
detail::get_id<cmd_function<T>>(), std::move(command));
330 auto run(std::ostream& output) -> bool;
332 auto run(std::ostream& output, std::ostream& error) -> bool;
337 const std::string alternative_name =
"--" +
name;
338 for(
const auto& command_pair : commands_)
340 const auto command_type_id = command_pair.first;
341 const auto& command = command_pair.second;
342 if(command->name ==
name || command->alternative == alternative_name)
345 if(command_type_id != requested_id)
347 throw std::runtime_error(
"Invalid usage of the parameter " +
name +
" detected.");
351 auto cmd =
static_cast<cmd_argument<T>*
>(command.get());
360 throw std::runtime_error(
"The parameter " +
name +
" could not be found.");
371 catch(
const std::exception&)
378 auto get_if(
const std::string&
name, std::function<T(T)> callback)
const -> T
381 return callback(value);
401 auto
howto_use(const
std::unique_ptr<cmd_base>& command) const ->
std::
string;
406 const
std::
string appname_;
407 std::vector<
std::
string> arguments_;
408 std::vector<
std::pair<
std::uint64_t,
std::unique_ptr<cmd_base>>> commands_;