TU-Programmieren_2/lab3/modules/iue-po/po.hpp
2025-04-09 10:22:44 +02:00

61 lines
1.5 KiB
C++

#pragma once
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
namespace iue::po {
inline std::vector<std::string> init(int argc, char* argv[]) {
return {argv + 1, argv + argc};
}
enum struct option { optional, required };
template <typename T>
inline T get(std::vector<std::string> args, std::string option, T default_value, enum option op = option::optional) {
auto find_option = [&option](const std::string& arg) -> bool {
return arg.starts_with("-" + option) || arg.starts_with("--" + option);
};
const auto count = std::ranges::count_if(args, find_option);
if (count == 0) {
if (op == option::required) {
throw std::runtime_error("required option not provided: -/--" + option);
}
return default_value;
}
if (count > 1) {
throw std::runtime_error("option not unique: -/--" + option + " (count = " + std::to_string(count) + ")");
}
auto it = std::ranges::find_if(args, find_option);
auto value = std::next(it);
if (value == args.end()) {
throw std::runtime_error("option not followed by value: -/--" + option);
}
if (value->starts_with('-')) {
throw std::runtime_error("option -/--" + option + " not followed by value but another option -/--" + *value);
}
std::istringstream ss(*value);
ss.exceptions(std::ios::failbit);
T num;
try {
ss >> num;
} catch (std::exception& e) {
throw std::runtime_error("value for option -/--" + option + " could not be converted");
}
return num;
}
} // namespace iue::po