diff --git a/barretenberg/cpp/src/barretenberg/common/constexpr_utils.hpp b/barretenberg/cpp/src/barretenberg/common/constexpr_utils.hpp index d098be977cb..6eacac59e21 100644 --- a/barretenberg/cpp/src/barretenberg/common/constexpr_utils.hpp +++ b/barretenberg/cpp/src/barretenberg/common/constexpr_utils.hpp @@ -5,6 +5,21 @@ #include namespace bb { +namespace detail { + +/** + * @brief Create an index sequence from Min to Max (not included) with an increment of Inc + */ +template constexpr auto make_index_range() +{ + static_assert(Max >= Min); + static_assert(Inc >= 1); + return [](std::index_sequence) { + return std::index_sequence{}; + }(std::make_index_sequence<(Max - Min - 1) / Inc + 1>{}); +} + +} // namespace detail /** * @brief Implements a loop using a compile-time iterator. Requires c++20. @@ -55,37 +70,11 @@ namespace bb { */ template constexpr void constexpr_for(F&& f) { - // Call function `f()` iff Start < End - if constexpr (Start < End) { - // F must be a template lambda with a single **typed** template parameter that represents the iterator - // (e.g. [&](){ ... } is good) - // (and [&](){ ... } won't compile!) - - /** - * Explaining f.template operator()() - * - * The following line must explicitly tell the compiler that is a template parameter by using the - * `template` keyword. - * (if we wrote f(), the compiler could legitimately interpret `<` as a less than symbol) - * - * The fragment `f.template` tells the compiler that we're calling a *templated* member of `f`. - * The "member" being called is the function operator, `operator()`, which must be explicitly provided - * (for any function X, `X(args)` is an alias for `X.operator()(args)`) - * The compiler has no alias `X.template (args)` for `X.template operator()(args)` so we must - * write it explicitly here - * - * To summarize what the next line tells the compiler... - * 1. I want to call a member of `f` that expects one or more template parameters - * 2. The member of `f` that I want to call is the function operator - * 3. The template parameter is `Start` - * 4. The function operator itself contains no arguments - */ - f.template operator()(); - - // Once we have executed `f`, we recursively call the `constexpr_for` function, increasing the value of `Start` - // by `Inc` - constexpr_for(f); - } + // F must be a template lambda with a single **typed** template parameter that represents the iterator + // (e.g. [&](){ ... } is good) + // (and [&](){ ... } won't compile!) + constexpr auto indices = detail::make_index_range(); + [&](std::index_sequence) { (f.template operator()(), ...); }(indices); } }; // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/relations/utils.hpp b/barretenberg/cpp/src/barretenberg/relations/utils.hpp index 49fedad8c38..0d3ae711ba1 100644 --- a/barretenberg/cpp/src/barretenberg/relations/utils.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/utils.hpp @@ -140,14 +140,6 @@ template class RelationUtils { } } - // This is an simpler, iterative version of constexpr_for. - // Replace it with constexpr_for once that one is iterative. - template static constexpr void iterative_constexpr_for(F&& f) - { - auto seq = std::make_index_sequence{}; - [&](std::index_sequence) { (f.template operator()(), ...); }(seq); - } - /** * @brief Calculate the contribution of each relation to the expected value of the full Honk relation. * @@ -164,7 +156,7 @@ template class RelationUtils { const Parameters& relation_parameters, const FF& partial_evaluation_result) { - iterative_constexpr_for([&]() { + constexpr_for<0, NUM_RELATIONS, 1>([&]() { // FIXME: You wan't /*consider_skipping=*/false here, but tests need to be fixed. accumulate_single_relation( evaluations, relation_evaluations, relation_parameters, partial_evaluation_result); @@ -187,7 +179,7 @@ template class RelationUtils { const Parameters& relation_parameters, const FF& partial_evaluation_result) { - iterative_constexpr_for([&]() { + constexpr_for<0, NUM_RELATIONS, 1>([&]() { accumulate_single_relation( evaluations, relation_evaluations, relation_parameters, partial_evaluation_result); });