Recursively flattens nested ANDs, ORs or eligible callable expressions into a vector of their inputs. Recursive flattening ceases exploring an input branch if it encounters either an expression different from 'flattenCall' or its inputs are not the same type. Examples: flattenCall: AND in: a AND (b AND (c AND d)) out: [a, b, c, d] flattenCall: OR in: (a OR b) OR (c OR d) out: [a, b, c, d] flatte
| 162 | // in: (array1, concat(array2, concat(array2, intVal)) |
| 163 | // out: [array1, array2, concat(array2, intVal)] |
| 164 | void flattenInput( |
| 165 | const TypedExprPtr& input, |
| 166 | const std::string& flattenCall, |
| 167 | std::vector<TypedExprPtr>& flat) { |
| 168 | if (isCall(input, flattenCall) && allInputTypesEquivalent(input)) { |
| 169 | for (auto& child : input->inputs()) { |
| 170 | flattenInput(child, flattenCall, flat); |
| 171 | } |
| 172 | } else { |
| 173 | flat.emplace_back(input); |
| 174 | } |
| 175 | } |
| 176 | |
| 177 | ExprPtr getAlreadyCompiled(const ITypedExpr* expr, ExprDedupMap* visited) { |
| 178 | auto iter = visited->find(expr); |
no test coverage detected