Define a new context to evaluate an expression in This is essentially a dynamic scope mechanism
| 99 | /// Define a new context to evaluate an expression in |
| 100 | /// This is essentially a dynamic scope mechanism |
| 101 | class FieldContext : public FieldGenerator { |
| 102 | public: |
| 103 | using variable_list = std::vector<std::pair<string, FieldGeneratorPtr>>; |
| 104 | |
| 105 | /// Create with a list of context variables to modify |
| 106 | /// and an expression to evaluate in that new context |
| 107 | FieldContext(variable_list variables, FieldGeneratorPtr expr) |
| 108 | : variables(std::move(variables)), expr(std::move(expr)) {} |
| 109 | |
| 110 | double generate(const Context& ctx) override { |
| 111 | // Create a new context |
| 112 | Context new_context{ctx}; |
| 113 | |
| 114 | // Set values in the context by evaluating the generators |
| 115 | for (auto const& var : variables) { |
| 116 | new_context.set(var.first, var.second->generate(ctx)); |
| 117 | } |
| 118 | |
| 119 | // Evaluate the expression in the new context |
| 120 | return expr->generate(new_context); |
| 121 | } |
| 122 | std::string str() const override { |
| 123 | auto result = "["s; |
| 124 | for (auto const& var : variables) { |
| 125 | result += var.first + "="s + var.second->str() + ","s; |
| 126 | } |
| 127 | result += "]("s + expr->str() + ")"s; |
| 128 | return result; |
| 129 | } |
| 130 | |
| 131 | private: |
| 132 | variable_list variables; ///< A list of context variables to modify |
| 133 | FieldGeneratorPtr expr; ///< The expression to evaluate in the new context |
| 134 | }; |
| 135 | |
| 136 | /// Sum expressions in a loop, given symbol, count and expression |
| 137 | class FieldSum : public FieldGenerator { |
nothing calls this directly
no outgoing calls
no test coverage detected