Startup returns a unique_ptr instead of using a static

This commit is contained in:
Eric Mertens 2022-11-21 18:49:22 -08:00
parent b053686349
commit cb70a0b1d2
34 changed files with 67 additions and 44 deletions

View File

@ -238,7 +238,7 @@ TEST_SUITE("documented examples") {
} }
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto program = Parse(aocpp::Startup(argc, argv)); auto const program = Parse(*aocpp::Startup(argc, argv));
std::cout << "Part 1: " << Part1(program) << std::endl; std::cout << "Part 1: " << Part1(program) << std::endl;
std::cout << "Part 2: " << Part2(program) << std::endl; std::cout << "Part 2: " << Part2(program) << std::endl;
} }

View File

@ -45,7 +45,8 @@ TEST_CASE("part 2") {
} }
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto& in = aocpp::Startup(argc, argv); auto in_ptr = aocpp::Startup(argc, argv);
auto & in = *in_ptr;
std::int64_t weight; std::int64_t weight;
std::int64_t part1 = 0; std::int64_t part1 = 0;

View File

@ -37,7 +37,7 @@ TEST_SUITE("documented examples") {
} }
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto machine = Machine{ParseStream(aocpp::Startup(argc, argv))}; auto machine = Machine{ParseStream(*aocpp::Startup(argc, argv))};
std::cout << "Part 1: " << Compute(machine, 12, 2) << std::endl; std::cout << "Part 1: " << Compute(machine, 12, 2) << std::endl;

View File

@ -67,7 +67,8 @@ auto Record (
} // namespace } // namespace
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto& in = aocpp::Startup(argc, argv); auto in_ptr = aocpp::Startup(argc, argv);
auto & in = *in_ptr;
std::string line; std::string line;
std::getline(in, line); std::getline(in, line);

View File

@ -44,7 +44,7 @@ auto Valid2(std::string const& str) {
} // namespace } // namespace
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto [lo,hi] = Parse(aocpp::Startup(argc, argv)); auto [lo,hi] = Parse(*aocpp::Startup(argc, argv));
std::int64_t part1 = 0; std::int64_t part1 = 0;
std::int64_t part2 = 0; std::int64_t part2 = 0;

View File

@ -18,7 +18,7 @@ auto Compute(Machine machine, ValueType d) -> ValueType {
} // namespace } // namespace
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto machine = Machine{ParseStream(aocpp::Startup(argc, argv))}; auto machine = Machine{ParseStream(*aocpp::Startup(argc, argv))};
std::cout << "Part 1: " << Compute(machine, 1) << std::endl; std::cout << "Part 1: " << Compute(machine, 1) << std::endl;
std::cout << "Part 2: " << Compute(std::move(machine), 5) << std::endl; std::cout << "Part 2: " << Compute(std::move(machine), 5) << std::endl;
} }

View File

@ -89,7 +89,7 @@ TEST_SUITE("documented examples") {
} }
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto parents = Parse(aocpp::Startup(argc, argv)); auto parents = Parse(*aocpp::Startup(argc, argv));
std::cout << "Part 1: " << Part1(parents) << std::endl; std::cout << "Part 1: " << Part1(parents) << std::endl;
std::cout << "Part 2: " << Part2(parents) << std::endl; std::cout << "Part 2: " << Part2(parents) << std::endl;
} }

View File

@ -86,7 +86,7 @@ TEST_SUITE("documented examples") {
} }
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto machine = Machine{ParseStream(aocpp::Startup(argc, argv))}; auto machine = Machine{ParseStream(*aocpp::Startup(argc, argv))};
std::cout << "Part 1: " << Part1(machine) << std::endl; std::cout << "Part 1: " << Part1(machine) << std::endl;
std::cout << "Part 2: " << Part2(std::move(machine)) << std::endl; std::cout << "Part 2: " << Part2(std::move(machine)) << std::endl;
} }

View File

@ -58,7 +58,7 @@ auto Draw(std::string const& picture) {
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
std::string line; std::string line;
std::getline(aocpp::Startup(argc, argv), line); std::getline(*aocpp::Startup(argc, argv), line);
std::cout << "Part 1: " << Part1(line) << std::endl; std::cout << "Part 1: " << Part1(line) << std::endl;
Draw(Flatten(line)); Draw(Flatten(line));
} }

View File

@ -30,7 +30,7 @@ TEST_SUITE("documented examples") {
} }
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto machine = Machine{ParseStream(aocpp::Startup(argc, argv))}; auto machine = Machine{ParseStream(*aocpp::Startup(argc, argv))};
std::cout << "Part 1: " << Compute(machine, 1) << std::endl; std::cout << "Part 1: " << Compute(machine, 1) << std::endl;
std::cout << "Part 2: " << Compute(std::move(machine), 2) << std::endl; std::cout << "Part 2: " << Compute(std::move(machine), 2) << std::endl;
} }

View File

@ -209,7 +209,7 @@ TEST_SUITE("documented examples") {
} }
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto grid = Grid::Parse(Startup(argc, argv)); auto grid = Grid::Parse(*Startup(argc, argv));
auto [part1, base] = Part1(grid); auto [part1, base] = Part1(grid);
std::cout << "Part 1: " << part1 << std::endl; std::cout << "Part 1: " << part1 << std::endl;
std::cout << "Part 2: " << Part2(grid, base, 200) << std::endl; std::cout << "Part 2: " << Part2(grid, base, 200) << std::endl;

View File

@ -38,7 +38,7 @@ auto Compute(Machine machine, ValueType start)
} // namespace } // namespace
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto machine = Machine{ParseStream(aocpp::Startup(argc, argv))}; auto machine = Machine{ParseStream(*aocpp::Startup(argc, argv))};
std::cout << "Part 1: " << Compute(machine, 0).size() << "\nPart 2\n"; std::cout << "Part 1: " << Compute(machine, 0).size() << "\nPart 2\n";
Draw(std::cout, Compute(std::move(machine), 1)); Draw(std::cout, Compute(std::move(machine), 1));
} }

View File

@ -94,7 +94,7 @@ auto Part2(std::array<std::vector<Particle>, 3> const& ps) {
} // namespace } // namespace
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto ps = Parse(aocpp::Startup(argc, argv)); auto ps = Parse(*aocpp::Startup(argc, argv));
auto part2 = Part2(ps); auto part2 = Part2(ps);
auto part1 = Part1(std::move(ps), 1000); auto part1 = Part1(std::move(ps), 1000);

View File

@ -60,7 +60,7 @@ auto Compute2(Machine machine) {
} // namespace } // namespace
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto machine = Machine{ParseStream(aocpp::Startup(argc, argv))}; auto machine = Machine{ParseStream(*aocpp::Startup(argc, argv))};
std::cout << "Part 1: " << Compute1(machine) << std::endl; std::cout << "Part 1: " << Compute1(machine) << std::endl;
std::cout << "Part 2: " << Compute2(std::move(machine)) << std::endl; std::cout << "Part 2: " << Compute2(std::move(machine)) << std::endl;
} }

View File

@ -229,7 +229,7 @@ TEST_SUITE("documented examples") {
} }
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto recipes = Parse(aocpp::Startup(argc, argv)); auto recipes = Parse(*aocpp::Startup(argc, argv));
auto machine = Machine(recipes); auto machine = Machine(recipes);
auto part1 = machine(1); auto part1 = machine(1);
auto part2 = ComputeFuel(machine, 1'000'000'000'000); auto part2 = ComputeFuel(machine, 1'000'000'000'000);

View File

@ -91,7 +91,7 @@ auto Compute(std::map<Coord, ValueType> world) -> std::pair<int, int> {
} // namespace } // namespace
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto [p1,p2] = Compute(Explore(Machine{ParseStream(aocpp::Startup(argc, argv))})); auto [p1,p2] = Compute(Explore(Machine{ParseStream(*aocpp::Startup(argc, argv))}));
std::cout << "Part 1: " << p1 << std::endl; std::cout << "Part 1: " << p1 << std::endl;
std::cout << "Part 2: " << p2 << std::endl; std::cout << "Part 2: " << p2 << std::endl;
} }

View File

@ -119,7 +119,7 @@ TEST_SUITE("documented examples") {
} }
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto input = Parse(aocpp::Startup(argc, argv)); auto input = Parse(*aocpp::Startup(argc, argv));
std::cout << "Part 1: " << Compute(input, 100, 0) << std::endl; std::cout << "Part 1: " << Compute(input, 100, 0) << std::endl;
std::cout << "Part 2: " << Part2(input) << std::endl; std::cout << "Part 2: " << Part2(input) << std::endl;

View File

@ -214,7 +214,7 @@ auto GatherScore(Machine m, std::string const& program) -> ValueType {
} // namespace } // namespace
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto machine = Machine{ParseStream(aocpp::Startup(argc, argv))}; auto machine = Machine{ParseStream(*aocpp::Startup(argc, argv))};
auto grid = GatherOutput(machine); auto grid = GatherOutput(machine);
auto part1 = ScaffoldAlignments(grid); auto part1 = ScaffoldAlignments(grid);
auto path = ComputePath(grid); auto path = ComputePath(grid);

View File

@ -160,7 +160,7 @@ auto Part2(Grid & grid, Features & features) {
} // namespace } // namespace
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto grid = Grid::Parse(Startup(argc, argv)); auto grid = Grid::Parse(*Startup(argc, argv));
auto features = FindFeatures(grid); auto features = FindFeatures(grid);
auto distances = FindDistances(grid, features); auto distances = FindDistances(grid, features);
std::cout << "Part 1: " << SolveMaze(distances, "@") << std::endl; std::cout << "Part 1: " << SolveMaze(distances, "@") << std::endl;

View File

@ -46,7 +46,7 @@ auto Part2(Scanner const& scanner) {
} // namespace } // namespace
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto scanner = Scanner{Machine{ParseStream(aocpp::Startup(argc, argv))}}; auto scanner = Scanner{Machine{ParseStream(*aocpp::Startup(argc, argv))}};
std::cout << "Part 1: " << Part1(scanner) << std::endl; std::cout << "Part 1: " << Part1(scanner) << std::endl;
std::cout << "Part 2: " << Part2(scanner) << std::endl; std::cout << "Part 2: " << Part2(scanner) << std::endl;
} }

View File

@ -150,7 +150,7 @@ auto SolveMaze(Distances const& distances, bool const recursive) -> std::int64_t
} // namespace } // namespace
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto map = Grid::Parse(Startup(argc, argv)); auto map = Grid::Parse(*Startup(argc, argv));
auto portals = FindPortals(map); auto portals = FindPortals(map);
auto distances = FindDistances(map, portals); auto distances = FindDistances(map, portals);

View File

@ -263,7 +263,7 @@ auto Compute(
} // namespace } // namespace
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
Machine machine {ParseStream(aocpp::Startup(argc, argv))}; Machine machine {ParseStream(*aocpp::Startup(argc, argv))};
Compute(machine, 4, Compute(machine, 4,
{ "#####.###########", { "#####.###########",

View File

@ -115,7 +115,7 @@ auto Many(Shuffle<Cards> shuffle, unsigned long n) -> Shuffle<Cards> {
} // namespace } // namespace
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto instructions = Parse(Startup(argc, argv)); auto instructions = Parse(*Startup(argc, argv));
auto shuffle1 = FollowInstructions<10007>(instructions); auto shuffle1 = FollowInstructions<10007>(instructions);
std::cout << "Part 1: " << shuffle1(2019) << std::endl; std::cout << "Part 1: " << shuffle1(2019) << std::endl;

View File

@ -56,7 +56,7 @@ auto Interact(Ethernet & ethernet, Machine & m, std::optional<Payload> p) -> voi
} // namespace } // namespace
auto main(int const argc, char** const argv) -> int { auto main(int const argc, char** const argv) -> int {
auto machines = BuildNetwork(Machine{ParseStream(aocpp::Startup(argc, argv))}); auto machines = BuildNetwork(Machine{ParseStream(*aocpp::Startup(argc, argv))});
auto ethernet = Ethernet{}; auto ethernet = Ethernet{};
std::optional<ValueType> part1; std::optional<ValueType> part1;

View File

@ -84,8 +84,8 @@ auto Step(std::vector<C> const& bugs, F with_neighbors = F{})
case 2: case 2:
if (!std::binary_search(bugs.begin(), bugs.end(), k)) { if (!std::binary_search(bugs.begin(), bugs.end(), k)) {
result.push_back(k); result.push_back(k);
break;
} }
break;
} }
} }
@ -136,7 +136,7 @@ TEST_SUITE("documented examples") {
} }
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto const bugs = FindBugs(Grid::Parse(Startup(argc, argv))); auto const bugs = FindBugs(Grid::Parse(*Startup(argc, argv)));
std::cout << "Part 1: " << Part1(bugs) << std::endl; std::cout << "Part 1: " << Part1(bugs) << std::endl;
std::cout << "Part 2: " << Part2(std::move(bugs), 200) << std::endl; std::cout << "Part 2: " << Part2(std::move(bugs), 200) << std::endl;
} }

View File

@ -76,5 +76,5 @@ auto main(int argc, char** argv) -> int {
Search(script); Search(script);
RunWithIO(Machine{ParseStream(aocpp::Startup(argc, argv))}, script); RunWithIO(Machine{ParseStream(*aocpp::Startup(argc, argv))}, script);
} }

View File

@ -57,7 +57,9 @@ TEST_CASE("part 2") {
} }
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto & in = aocpp::Startup(argc, argv); auto const in_ptr = aocpp::Startup(argc, argv);
auto & in = *in_ptr;
std::uint64_t part1{}, part2{}; std::uint64_t part1{}, part2{};
std::string line; std::string line;

View File

@ -76,7 +76,7 @@ TEST_CASE("part 2") {
} }
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto grid = Grid::Parse(Startup(argc, argv)); auto grid = Grid::Parse(*Startup(argc, argv));
std::cout << "Part 1: " << Part1(grid) << std::endl; std::cout << "Part 1: " << Part1(grid) << std::endl;
std::cout << "Part 2: " << Part2(grid) << std::endl; std::cout << "Part 2: " << Part2(grid) << std::endl;
} }

View File

@ -76,7 +76,7 @@ TEST_CASE("part 2") {
} }
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto adapters = Parse(aocpp::Startup(argc, argv)); auto adapters = Parse(*aocpp::Startup(argc, argv));
std::cout << "Part 1: " << Part1(adapters) << std::endl; std::cout << "Part 1: " << Part1(adapters) << std::endl;
std::cout << "Part 2: " << Part2(adapters) << std::endl; std::cout << "Part 2: " << Part2(adapters) << std::endl;
} }

View File

@ -185,7 +185,7 @@ TEST_SUITE("documented examples") {
} }
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto input = Parse(aocpp::Startup(argc, argv)); auto input = Parse(*aocpp::Startup(argc, argv));
std::cout << "Part 1: " << Part1(input) << std::endl; std::cout << "Part 1: " << Part1(input) << std::endl;
std::cout << "Part 2: " << Part2(input) << std::endl; std::cout << "Part 2: " << Part2(input) << std::endl;
} }

View File

@ -141,7 +141,8 @@ TEST_CASE("errors") {
} }
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto & in = aocpp::Startup(argc, argv); auto const in_ptr = aocpp::Startup(argc, argv);
auto & in = *in_ptr;
std::int64_t part1 = 0; std::int64_t part1 = 0;
std::int64_t part2 = 0; std::int64_t part2 = 0;

View File

@ -179,7 +179,7 @@ TEST_CASE("part 2") {
} }
auto main(int argc, char** argv) -> int { auto main(int argc, char** argv) -> int {
auto input = Parse(Startup(argc, argv)); auto const input = Parse(*Startup(argc, argv));
std::cout << "Part 1: " << Part1(input) << std::endl; std::cout << "Part 1: " << Part1(input) << std::endl;
std::cout << "Part 2: " << Part2(input) << std::endl; std::cout << "Part 2: " << Part2(input) << std::endl;
} }

View File

@ -3,11 +3,23 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <memory>
#include <optional> #include <optional>
namespace aocpp { namespace aocpp {
auto Startup(int argc, char ** argv) -> std::istream&; class ConditionalDeleter {
bool should_delete_;
public:
ConditionalDeleter(bool should_delete) : should_delete_ {should_delete} {}
template <typename T>
auto operator()(T * pointer) -> void { if (should_delete_) { delete pointer; }}
};
auto Startup(int argc, char ** argv) -> std::unique_ptr<std::istream, ConditionalDeleter>;
} }
#endif #endif

View File

@ -12,19 +12,25 @@
namespace aocpp { namespace aocpp {
auto Startup(int argc, char ** argv) -> std::istream& { auto Startup(int argc, char ** argv) -> std::unique_ptr<std::istream, ConditionalDeleter> {
if (std::getenv("DOCTEST")) { bool should_delete;
exit(doctest::Context{argc, argv}.run()); std::istream* result_ptr;
}
static std::ifstream fin;
switch (argc) { switch (argc) {
case 2: fin = std::ifstream{argv[1]}; return fin; case 2:
case 1: return std::cin; should_delete = true;
result_ptr = new std::ifstream{argv[1]};
break;
case 1:
should_delete = false;
result_ptr = &std::cin;
break;
default: default:
std::cerr << "bad arguments\n"; std::cerr << "bad arguments\n";
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
return {result_ptr, should_delete};
} }
} }