#pragma once #include #include #include #include namespace iue::po { inline std::vector init(int argc, char* argv[]) { return {argv + 1, argv + argc}; } enum struct option { optional, required }; template inline T get(std::vector 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