// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include #include #include #include constexpr size_t loop_cnt = 64; using namespace search::queryeval; struct ItemAdapter { double estimate(const auto &child) const noexcept { return child.rel_est; } double cost(const auto &child) const noexcept { return child.cost; } double strict_cost(const auto &child) const noexcept { return child.strict_cost; } }; struct Item { double rel_est; double cost; double strict_cost; Item(double rel_est_in, double cost_in, double strict_cost_in) noexcept : rel_est(rel_est_in), cost(cost_in), strict_cost(strict_cost_in) {} template static double estimate_of(std::vector &data) { return FLOW::estimate_of(ItemAdapter(), data); } template static void sort(std::vector &data, bool strict) { FLOW::sort(ItemAdapter(), data, strict); } template static double cost_of(const std::vector &data, bool strict) { return FLOW::cost_of(ItemAdapter(), data, strict); } template static double ordered_cost_of(const std::vector &data, bool strict) { return flow::ordered_cost_of(ItemAdapter(), data, FLOW(1.0, strict)); } auto operator <=>(const Item &rhs) const noexcept = default; }; std::vector gen_data(size_t size) { static std::mt19937 gen; static std::uniform_real_distribution rel_est(0.1, 0.9); static std::uniform_real_distribution cost(1.0, 10.0); static std::uniform_real_distribution strict_cost(0.1, 5.0); std::vector result; result.reserve(size); for (size_t i = 0; i < size; ++i) { result.emplace_back(rel_est(gen), cost(gen), strict_cost(gen)); } return result; } template void each_perm(std::vector &data, size_t k, F fun) { if (k <= 1) { fun(const_cast &>(data)); } else { each_perm(data, k-1, fun); for (size_t i = 0; i < k-1; ++i) { if (k & 1) { std::swap(data[0], data[k-1]); } else { std::swap(data[i], data[k-1]); } each_perm(data, k-1, fun); } } } template void each_perm(std::vector &data, F fun) { each_perm(data, data.size(), fun); } TEST(FlowTest, perm_test) { std::set> seen; std::vector data = {1,2,3,4,5}; auto hook = [&](const std::vector &perm) { EXPECT_EQ(perm.size(), 5); seen.insert(perm); }; each_perm(data, hook); EXPECT_EQ(seen.size(), 120); } template