Improve command line parser.

This commit is contained in:
2019-09-12 11:43:46 +02:00
parent cd4c32c2a3
commit 62f3e4c5de
2 changed files with 40 additions and 24 deletions

View File

@@ -2,9 +2,11 @@ cmake_minimum_required(VERSION 3.15)
project(aoc2019)
find_package(Boost REQUIRED COMPONENTS program_options)
add_library(AoCSolutions src/solutions.hpp src/solutions.cpp src/day01.cpp)
target_compile_features(AoCSolutions PUBLIC cxx_std_17)
add_executable(runner src/runner.cpp)
target_compile_features(runner PUBLIC cxx_std_17)
target_link_libraries(runner AoCSolutions)
target_link_libraries(runner AoCSolutions Boost::program_options)

View File

@@ -1,34 +1,48 @@
#include "solutions.hpp"
#include <iostream>
#include <charconv>
#include <cstring>
#include <boost/program_options.hpp>
template<typename Int, int Radix = 10>
Int int_from_cstr(Int &value, const char *begin) {
const char *end = begin + std::strlen(begin);
auto result = std::from_chars(begin, end, value, Radix);
if (result.ec != std::errc()) {
throw std::invalid_argument("Unparseable integer");
}
namespace po = boost::program_options;
return value;
struct AoCOptions {
int day;
bool part2;
};
AoCOptions parse_options(const int argc, const char* argv[]) {
AoCOptions options{};
po::options_description desc("Allowed options");
desc.add_options()
("day", po::value<int>(&options.day)->required(), "The day to run.")
("part2,2", po::bool_switch(&options.part2), "Whether to run part 2.");
po::positional_options_description positionals;
positionals.add("day", 1);
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(desc).positional(positionals).run(), vm);
po::notify(vm);
return options;
}
int main(int argc, const char *argv[]) {
if (argc < 2) {
std::cerr << "Specify a day to run.\n";
try {
const auto options = parse_options(argc, argv);
const aoc2019::solution_t solution = aoc2019::get_implementation(options.day, options.part2);
if (solution != nullptr) {
solution(std::cin, std::cout);
return 0;
} else {
std::cerr << "Unimplemented.\n";
return 1;
}
} catch (po::required_option &ignored) {
return 1;
}
int day;
int_from_cstr(day, argv[1]);
const aoc2019::solution_t solution = aoc2019::get_implementation(day);
if (solution != nullptr) {
solution(std::cin, std::cout);
return 0;
} else {
std::cerr << "Unimplemented.\n";
} catch (std::out_of_range &ignored) {
std::cerr << "Invalid day.\n";
return 1;
}
}