mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-27 05:40:32 +01:00
No longer depend on Boost.program_options.
This commit is contained in:
@@ -2,7 +2,6 @@ cmake_minimum_required(VERSION 3.12)
|
|||||||
|
|
||||||
project(aoc2019)
|
project(aoc2019)
|
||||||
|
|
||||||
find_package(Boost REQUIRED COMPONENTS program_options)
|
|
||||||
find_package(GTest REQUIRED)
|
find_package(GTest REQUIRED)
|
||||||
|
|
||||||
add_library(AoCSolutions src/implementations.hpp src/implementations.cpp src/day01.cpp src/days.hpp)
|
add_library(AoCSolutions src/implementations.hpp src/implementations.cpp src/day01.cpp src/days.hpp)
|
||||||
@@ -10,7 +9,7 @@ target_compile_features(AoCSolutions PUBLIC cxx_std_17)
|
|||||||
|
|
||||||
add_executable(runner src/runner.cpp)
|
add_executable(runner src/runner.cpp)
|
||||||
target_compile_features(runner PUBLIC cxx_std_17)
|
target_compile_features(runner PUBLIC cxx_std_17)
|
||||||
target_link_libraries(runner AoCSolutions Boost::program_options)
|
target_link_libraries(runner AoCSolutions)
|
||||||
|
|
||||||
add_executable(unit_tests tests/test_solutions.cpp)
|
add_executable(unit_tests tests/test_solutions.cpp)
|
||||||
target_compile_features(unit_tests PUBLIC cxx_std_17)
|
target_compile_features(unit_tests PUBLIC cxx_std_17)
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ Install the dependencies:
|
|||||||
by default tries to dynamically link GTest, and the Ubuntu packages
|
by default tries to dynamically link GTest, and the Ubuntu packages
|
||||||
only provide a statically linked archive. You may need to compile it
|
only provide a statically linked archive. You may need to compile it
|
||||||
for yourself.
|
for yourself.
|
||||||
- [Boost.Program_options](https://www.boost.org/doc/libs/1_71_0/doc/html/program_options.html)
|
|
||||||
|
|
||||||
```
|
```
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
#include "implementations.hpp"
|
#include "implementations.hpp"
|
||||||
|
#include <charconv>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/program_options.hpp>
|
|
||||||
|
|
||||||
namespace po = boost::program_options;
|
|
||||||
|
|
||||||
struct AoCOptions {
|
struct AoCOptions {
|
||||||
aoc2019::solution_t implementation;
|
aoc2019::solution_t implementation;
|
||||||
@@ -11,35 +9,84 @@ struct AoCOptions {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static AoCOptions parse_options(const int argc, const char* argv[]) {
|
static AoCOptions parse_options(const int argc, const char* argv[]) {
|
||||||
|
using namespace std::string_view_literals;
|
||||||
AoCOptions options{};
|
AoCOptions options{};
|
||||||
int day;
|
|
||||||
bool part2;
|
|
||||||
po::options_description desc("Allowed options");
|
|
||||||
desc.add_options()
|
|
||||||
("day", po::value<int>(&day)->required(), "The day to run.")
|
|
||||||
("part2,2", po::bool_switch(&part2), "Whether to run part 2.")
|
|
||||||
("timer,t", po::bool_switch(&options.run_timer), "Show the execution time.");
|
|
||||||
|
|
||||||
po::positional_options_description positionals;
|
auto show_help = [argv] (int exit_status = 0) {
|
||||||
positionals.add("day", 1);
|
std::cerr << "Usage: " << argv[0] << " [--timer|-t] [--part2|-2] [--help|-h] DAY\n"
|
||||||
|
<< "\t--timer|-t: print execution time\n"
|
||||||
|
<< "\t--part2|-2: run part 2\n"
|
||||||
|
<< "\t --help|-h: show this message\n";
|
||||||
|
std::exit(exit_status);
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
int day = -1;
|
||||||
po::variables_map vm;
|
bool part2 = false;
|
||||||
|
|
||||||
po::store(po::command_line_parser(argc, argv).options(desc).positional(positionals).run(), vm);
|
// Here follows a manual implementation of getopt, since getopt doesn't work on windows…
|
||||||
po::notify(vm);
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
std::string_view arg(argv[i]);
|
||||||
|
if (arg[0] == '-') {
|
||||||
|
// Handle flag arguments
|
||||||
|
if (arg[1] != '-') {
|
||||||
|
// Shorthand flags
|
||||||
|
for (char c : arg.substr(1)) {
|
||||||
|
switch (c) {
|
||||||
|
case '2':
|
||||||
|
part2 = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 't':
|
||||||
|
options.run_timer = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
show_help();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
std::cerr << "Unknown flag '" << c << "'.\n\n";
|
||||||
|
show_help(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Handle long form versions
|
||||||
|
if (arg == "--timer"sv) {
|
||||||
|
part2 = true;
|
||||||
|
} else if (arg == "--timer"sv) {
|
||||||
|
options.run_timer = true;
|
||||||
|
} else if (arg == "--help"sv) {
|
||||||
|
show_help();
|
||||||
|
} else {
|
||||||
|
show_help(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (day != -1) {
|
||||||
|
// Double date specification, bail.
|
||||||
|
show_help(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to parse the date number
|
||||||
|
if (auto res = std::from_chars(arg.data(), arg.data() + arg.size(), day); res.ec != std::errc()) {
|
||||||
|
auto error_code = std::make_error_code(res.ec);
|
||||||
|
std::cerr << error_code.message() << "\n\n";
|
||||||
|
show_help(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (day == -1) {
|
||||||
|
std::cerr << "Argument DAY is required.\n\n";
|
||||||
|
show_help(1);
|
||||||
|
} else if (day < 1 || day > 25) {
|
||||||
|
std::cerr << "Invalid day. Valid range: [1, 25]\n";
|
||||||
|
show_help(1);
|
||||||
|
}
|
||||||
|
|
||||||
options.implementation = aoc2019::get_implementation(day, part2);
|
options.implementation = aoc2019::get_implementation(day, part2);
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
} catch (po::error &argument_error) {
|
|
||||||
std::cerr << argument_error.what() << std::endl;
|
|
||||||
std::exit(1);
|
|
||||||
} catch (std::out_of_range &) {
|
|
||||||
std::cerr << "Invalid day: " << day
|
|
||||||
<< ".\n Valid range: [1, 25].\n";
|
|
||||||
std::exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char *argv[]) {
|
int main(int argc, const char *argv[]) {
|
||||||
|
|||||||
Reference in New Issue
Block a user