diff --git a/2017/18.cpp b/2017/18.cpp index f1ef275..fa35066 100644 --- a/2017/18.cpp +++ b/2017/18.cpp @@ -238,7 +238,7 @@ TEST_SUITE("documented examples") { } 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 2: " << Part2(program) << std::endl; } diff --git a/2019/01.cpp b/2019/01.cpp index a5c670a..75a33f8 100644 --- a/2019/01.cpp +++ b/2019/01.cpp @@ -45,7 +45,8 @@ TEST_CASE("part 2") { } 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 part1 = 0; diff --git a/2019/02.cpp b/2019/02.cpp index 547e952..14770f6 100644 --- a/2019/02.cpp +++ b/2019/02.cpp @@ -37,7 +37,7 @@ TEST_SUITE("documented examples") { } 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; diff --git a/2019/03.cpp b/2019/03.cpp index e899191..ae8ffe5 100644 --- a/2019/03.cpp +++ b/2019/03.cpp @@ -67,7 +67,8 @@ auto Record ( } // namespace 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::getline(in, line); diff --git a/2019/04.cpp b/2019/04.cpp index 9fd24fa..d6ade1a 100644 --- a/2019/04.cpp +++ b/2019/04.cpp @@ -44,7 +44,7 @@ auto Valid2(std::string const& str) { } // namespace 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 part2 = 0; diff --git a/2019/05.cpp b/2019/05.cpp index 5dd5c59..62f9b40 100644 --- a/2019/05.cpp +++ b/2019/05.cpp @@ -18,7 +18,7 @@ auto Compute(Machine machine, ValueType d) -> ValueType { } // namespace 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 2: " << Compute(std::move(machine), 5) << std::endl; } diff --git a/2019/06.cpp b/2019/06.cpp index 5892116..0830e11 100644 --- a/2019/06.cpp +++ b/2019/06.cpp @@ -89,7 +89,7 @@ TEST_SUITE("documented examples") { } 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 2: " << Part2(parents) << std::endl; } diff --git a/2019/07.cpp b/2019/07.cpp index 810805f..1b5182d 100644 --- a/2019/07.cpp +++ b/2019/07.cpp @@ -86,7 +86,7 @@ TEST_SUITE("documented examples") { } 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 2: " << Part2(std::move(machine)) << std::endl; } diff --git a/2019/08.cpp b/2019/08.cpp index a479f3f..4a8974d 100644 --- a/2019/08.cpp +++ b/2019/08.cpp @@ -58,7 +58,7 @@ auto Draw(std::string const& picture) { auto main(int argc, char** argv) -> int { 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; Draw(Flatten(line)); } diff --git a/2019/09.cpp b/2019/09.cpp index c25f2c7..96c7dcc 100644 --- a/2019/09.cpp +++ b/2019/09.cpp @@ -30,7 +30,7 @@ TEST_SUITE("documented examples") { } 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 2: " << Compute(std::move(machine), 2) << std::endl; } diff --git a/2019/10.cpp b/2019/10.cpp index 6e28f5a..0ca9e25 100644 --- a/2019/10.cpp +++ b/2019/10.cpp @@ -209,7 +209,7 @@ TEST_SUITE("documented examples") { } 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); std::cout << "Part 1: " << part1 << std::endl; std::cout << "Part 2: " << Part2(grid, base, 200) << std::endl; diff --git a/2019/11.cpp b/2019/11.cpp index 66aefb2..5b8740b 100644 --- a/2019/11.cpp +++ b/2019/11.cpp @@ -38,7 +38,7 @@ auto Compute(Machine machine, ValueType start) } // namespace 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"; Draw(std::cout, Compute(std::move(machine), 1)); } diff --git a/2019/12.cpp b/2019/12.cpp index fc092eb..685c832 100644 --- a/2019/12.cpp +++ b/2019/12.cpp @@ -94,7 +94,7 @@ auto Part2(std::array, 3> const& ps) { } // namespace 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 part1 = Part1(std::move(ps), 1000); diff --git a/2019/13.cpp b/2019/13.cpp index 0bd3048..2a3a5b9 100644 --- a/2019/13.cpp +++ b/2019/13.cpp @@ -60,7 +60,7 @@ auto Compute2(Machine machine) { } // namespace 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 2: " << Compute2(std::move(machine)) << std::endl; } diff --git a/2019/14.cpp b/2019/14.cpp index 760eb7a..ac450f0 100644 --- a/2019/14.cpp +++ b/2019/14.cpp @@ -229,7 +229,7 @@ TEST_SUITE("documented examples") { } 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 part1 = machine(1); auto part2 = ComputeFuel(machine, 1'000'000'000'000); diff --git a/2019/15.cpp b/2019/15.cpp index d6cab80..96b541b 100644 --- a/2019/15.cpp +++ b/2019/15.cpp @@ -91,7 +91,7 @@ auto Compute(std::map world) -> std::pair { } // namespace 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 2: " << p2 << std::endl; } diff --git a/2019/16.cpp b/2019/16.cpp index ceaa856..61e3c6a 100644 --- a/2019/16.cpp +++ b/2019/16.cpp @@ -119,7 +119,7 @@ TEST_SUITE("documented examples") { } 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 2: " << Part2(input) << std::endl; diff --git a/2019/17.cpp b/2019/17.cpp index aedf05f..d29e0e9 100644 --- a/2019/17.cpp +++ b/2019/17.cpp @@ -214,7 +214,7 @@ auto GatherScore(Machine m, std::string const& program) -> ValueType { } // namespace 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 part1 = ScaffoldAlignments(grid); auto path = ComputePath(grid); diff --git a/2019/18.cpp b/2019/18.cpp index b0ce910..b11ea30 100644 --- a/2019/18.cpp +++ b/2019/18.cpp @@ -160,7 +160,7 @@ auto Part2(Grid & grid, Features & features) { } // namespace 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 distances = FindDistances(grid, features); std::cout << "Part 1: " << SolveMaze(distances, "@") << std::endl; diff --git a/2019/19.cpp b/2019/19.cpp index 63abf22..b5e8f0f 100644 --- a/2019/19.cpp +++ b/2019/19.cpp @@ -46,7 +46,7 @@ auto Part2(Scanner const& scanner) { } // namespace 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 2: " << Part2(scanner) << std::endl; } diff --git a/2019/20.cpp b/2019/20.cpp index 773d62e..54d6d09 100644 --- a/2019/20.cpp +++ b/2019/20.cpp @@ -150,7 +150,7 @@ auto SolveMaze(Distances const& distances, bool const recursive) -> std::int64_t } // namespace 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 distances = FindDistances(map, portals); diff --git a/2019/21.cpp b/2019/21.cpp index 95c1e0a..af00136 100644 --- a/2019/21.cpp +++ b/2019/21.cpp @@ -263,7 +263,7 @@ auto Compute( } // namespace auto main(int argc, char** argv) -> int { - Machine machine {ParseStream(aocpp::Startup(argc, argv))}; + Machine machine {ParseStream(*aocpp::Startup(argc, argv))}; Compute(machine, 4, { "#####.###########", diff --git a/2019/22.cpp b/2019/22.cpp index de4f07a..f0a1f94 100644 --- a/2019/22.cpp +++ b/2019/22.cpp @@ -115,7 +115,7 @@ auto Many(Shuffle shuffle, unsigned long n) -> Shuffle { } // namespace auto main(int argc, char** argv) -> int { - auto instructions = Parse(Startup(argc, argv)); + auto instructions = Parse(*Startup(argc, argv)); auto shuffle1 = FollowInstructions<10007>(instructions); std::cout << "Part 1: " << shuffle1(2019) << std::endl; diff --git a/2019/23.cpp b/2019/23.cpp index 3f378dd..e4e272d 100644 --- a/2019/23.cpp +++ b/2019/23.cpp @@ -56,7 +56,7 @@ auto Interact(Ethernet & ethernet, Machine & m, std::optional p) -> voi } // namespace 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{}; std::optional part1; diff --git a/2019/24.cpp b/2019/24.cpp index 2640b7d..72e6620 100644 --- a/2019/24.cpp +++ b/2019/24.cpp @@ -84,8 +84,8 @@ auto Step(std::vector const& bugs, F with_neighbors = F{}) case 2: if (!std::binary_search(bugs.begin(), bugs.end(), k)) { result.push_back(k); - break; } + break; } } @@ -136,7 +136,7 @@ TEST_SUITE("documented examples") { } 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 2: " << Part2(std::move(bugs), 200) << std::endl; } diff --git a/2019/25.cpp b/2019/25.cpp index f75d163..e18cacd 100644 --- a/2019/25.cpp +++ b/2019/25.cpp @@ -76,5 +76,5 @@ auto main(int argc, char** argv) -> int { Search(script); - RunWithIO(Machine{ParseStream(aocpp::Startup(argc, argv))}, script); + RunWithIO(Machine{ParseStream(*aocpp::Startup(argc, argv))}, script); } diff --git a/2020/02.cpp b/2020/02.cpp index a2d5c75..d25aa90 100644 --- a/2020/02.cpp +++ b/2020/02.cpp @@ -57,7 +57,9 @@ TEST_CASE("part 2") { } 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::string line; diff --git a/2020/03.cpp b/2020/03.cpp index d283873..a06e007 100644 --- a/2020/03.cpp +++ b/2020/03.cpp @@ -76,7 +76,7 @@ TEST_CASE("part 2") { } 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 2: " << Part2(grid) << std::endl; } diff --git a/2020/10.cpp b/2020/10.cpp index 813b70c..05e85f7 100644 --- a/2020/10.cpp +++ b/2020/10.cpp @@ -76,7 +76,7 @@ TEST_CASE("part 2") { } 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 2: " << Part2(adapters) << std::endl; } diff --git a/2020/16.cpp b/2020/16.cpp index 3ce075f..7839184 100644 --- a/2020/16.cpp +++ b/2020/16.cpp @@ -185,7 +185,7 @@ TEST_SUITE("documented examples") { } 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 2: " << Part2(input) << std::endl; } diff --git a/2020/18.cpp b/2020/18.cpp index 804e06a..98b94f2 100644 --- a/2020/18.cpp +++ b/2020/18.cpp @@ -141,7 +141,8 @@ TEST_CASE("errors") { } 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 part2 = 0; diff --git a/2020/21.cpp b/2020/21.cpp index 0dd56e6..79edc15 100644 --- a/2020/21.cpp +++ b/2020/21.cpp @@ -179,7 +179,7 @@ TEST_CASE("part 2") { } 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 2: " << Part2(input) << std::endl; } diff --git a/lib/include/aocpp/Startup.hpp b/lib/include/aocpp/Startup.hpp index 3b007d8..01c612f 100644 --- a/lib/include/aocpp/Startup.hpp +++ b/lib/include/aocpp/Startup.hpp @@ -3,11 +3,23 @@ #include #include +#include #include 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 + auto operator()(T * pointer) -> void { if (should_delete_) { delete pointer; }} +}; + +auto Startup(int argc, char ** argv) -> std::unique_ptr; + } #endif diff --git a/lib/src/Startup.cpp b/lib/src/Startup.cpp index b8f725f..8b63eea 100644 --- a/lib/src/Startup.cpp +++ b/lib/src/Startup.cpp @@ -12,19 +12,25 @@ namespace aocpp { -auto Startup(int argc, char ** argv) -> std::istream& { - if (std::getenv("DOCTEST")) { - exit(doctest::Context{argc, argv}.run()); - } +auto Startup(int argc, char ** argv) -> std::unique_ptr { + bool should_delete; + std::istream* result_ptr; - static std::ifstream fin; switch (argc) { - case 2: fin = std::ifstream{argv[1]}; return fin; - case 1: return std::cin; - default: - std::cerr << "bad arguments\n"; - exit(EXIT_FAILURE); + case 2: + should_delete = true; + result_ptr = new std::ifstream{argv[1]}; + break; + case 1: + should_delete = false; + result_ptr = &std::cin; + break; + default: + std::cerr << "bad arguments\n"; + exit(EXIT_FAILURE); } + + return {result_ptr, should_delete}; } }