#include #include #include "serif/utils/dependencies/dependencies.hpp" namespace { namespace dependencies = serif::utils::dependencies; struct Source { }; template struct Stage { }; } TEST_CASE("Requested dependency branches follow topology independently of declaration order", "[unit][utils][dependencies]") { int input = 2; const auto context = dependencies::make_dependency_context(dependencies::borrow(input)); std::array calls{}; const auto branch = [&]() { return dependencies::make_computation, dependencies::InputList>>([&](const int value) { ++calls[Result]; return value + Result; }); }; const auto graph = dependencies::make_computation_graph( branch.template operator()<4, 2>(), dependencies::make_computation, dependencies::InputList, Stage<5>>>([&](const int left, const int right) { ++calls[6]; return left + right; }), branch.template operator()<2, 1>(), branch.template operator()<7, 3>(), branch.template operator()<5, 3>(), branch.template operator()<1, 0>(), dependencies::make_computation, dependencies::InputList>([&](const int value) { ++calls[0]; return value; }), branch.template operator()<3, 1>()); auto cache = dependencies::make_computation_cache(graph, context); REQUIRE(cache.try_prepare(context, dependencies::RequestedResults>{})); CHECK(cache.get>() == 9); CHECK(calls == std::array{1, 1, 1, 0, 1, 0, 0, 0}); REQUIRE(cache.try_prepare(context, dependencies::RequestedResults>{})); CHECK(cache.get>() == 20); CHECK(calls == std::array{1, 1, 1, 1, 1, 1, 1, 0}); input = 5; REQUIRE(cache.try_prepare(context, dependencies::RequestedResults, Stage<7>>{})); CHECK(cache.get>() == 12); CHECK(cache.get>() == 16); CHECK(calls == std::array{2, 2, 2, 2, 2, 1, 1, 1}); CHECK(cache.report().status>() == dependencies::PreparationStatus::not_required); CHECK(cache.report().status>() == dependencies::PreparationStatus::not_required); }