| 283 | } |
| 284 | |
| 285 | ConstantValue eval(EvalContext& context, const Args& args, SourceRange, |
| 286 | const CallExpression::SystemCallInfo& callInfo) const final { |
| 287 | ConstantValue arr = args[0]->eval(context); |
| 288 | if (!arr) |
| 289 | return nullptr; |
| 290 | |
| 291 | auto [iterExpr, iterVar] = callInfo.getIteratorInfo(); |
| 292 | auto guard = context.disableCaching(); |
| 293 | auto iterVal = context.createLocal(iterVar); |
| 294 | |
| 295 | SVQueue results; |
| 296 | if (arr.isMap()) { |
| 297 | auto doFind = [&, ie = iterExpr](auto it, auto end) { |
| 298 | for (; it != end; it++) { |
| 299 | *iterVal = it->second; |
| 300 | ConstantValue cv = ie->eval(context); |
| 301 | if (cv.isTrue()) { |
| 302 | if (isIndexed) |
| 303 | results.emplace_back(it->first); |
| 304 | else |
| 305 | results.emplace_back(it->second); |
| 306 | |
| 307 | if (mode != All) |
| 308 | break; |
| 309 | } |
| 310 | } |
| 311 | }; |
| 312 | |
| 313 | auto& cont = *arr.map(); |
| 314 | if (mode == Last) |
| 315 | doFind(std::rbegin(cont), std::rend(cont)); |
| 316 | else |
| 317 | doFind(std::begin(cont), std::end(cont)); |
| 318 | } |
| 319 | else { |
| 320 | auto doFind = [&, ie = iterExpr](auto begin, auto end) { |
| 321 | for (auto it = begin; it != end; it++) { |
| 322 | *iterVal = *it; |
| 323 | ConstantValue cv = ie->eval(context); |
| 324 | if (cv.isTrue()) { |
| 325 | if (isIndexed) { |
| 326 | auto dist = std::ranges::distance(begin, it); |
| 327 | if (mode == Last) |
| 328 | dist = std::ranges::distance(begin, end) - dist - 1; |
| 329 | |
| 330 | results.emplace_back(SVInt(32, (uint64_t)dist, true)); |
| 331 | } |
| 332 | else { |
| 333 | results.emplace_back(*it); |
| 334 | } |
| 335 | |
| 336 | if (mode != All) |
| 337 | break; |
| 338 | } |
| 339 | } |
| 340 | }; |
| 341 | |
| 342 | auto find = [&](auto& cont) { |
nothing calls this directly
no test coverage detected