| 358 | /// container of pairs (key, value). |
| 359 | template <typename Container, typename F, typename Filter> |
| 360 | static cmJSONHelper<Container> FilteredObject( |
| 361 | JsonErrors::ErrorGenerator const& error, F func, Filter filter) |
| 362 | { |
| 363 | return [error, func, filter](Container& out, Json::Value const* value, |
| 364 | cmJSONState* state) -> bool { |
| 365 | // NOTE Some compile-time code path don't use `filter` at all. |
| 366 | // So, suppress "unused lambda capture" warning is needed. |
| 367 | static_cast<void>(filter); |
| 368 | |
| 369 | if (!value) { |
| 370 | out.clear(); |
| 371 | return true; |
| 372 | } |
| 373 | if (!value->isObject()) { |
| 374 | error(value, state); |
| 375 | return false; |
| 376 | } |
| 377 | out.clear(); |
| 378 | auto outIt = std::inserter(out, out.end()); |
| 379 | bool success = true; |
| 380 | for (auto const& key : value->getMemberNames()) { |
| 381 | state->push_stack(key, &(*value)[key]); |
| 382 | #if __cplusplus >= 201703L |
| 383 | if constexpr (std::is_same_v<Filter, std::true_type>) { |
| 384 | // Filtering functionality isn't needed at all... |
| 385 | } else if constexpr (details::is_bool_filter<Filter>::value) { |
| 386 | // A given `Filter` is `bool(const std::string&)` callable. |
| 387 | if (!filter(key)) { |
| 388 | state->pop_stack(); |
| 389 | continue; |
| 390 | } |
| 391 | } else { |
| 392 | #endif |
| 393 | // A full-featured `Filter` has been given |
| 394 | auto res = filter(key, &(*value)[key], state); |
| 395 | if (res == FilterResult::Skip) { |
| 396 | state->pop_stack(); |
| 397 | continue; |
| 398 | } |
| 399 | if (res == FilterResult::Error) { |
| 400 | state->pop_stack(); |
| 401 | success = false; |
| 402 | break; |
| 403 | } |
| 404 | #if __cplusplus >= 201703L |
| 405 | } |
| 406 | #endif |
| 407 | typename Container::value_type::second_type t; |
| 408 | // ATTENTION Call the function first (for it's side-effects), |
| 409 | // then accumulate the result! |
| 410 | success = func(t, &(*value)[key], state) && success; |
| 411 | outIt = typename Container::value_type{ key, std::move(t) }; |
| 412 | state->pop_stack(); |
| 413 | } |
| 414 | return success; |
| 415 | }; |
| 416 | } |
| 417 |
nothing calls this directly
no test coverage detected
searching dependent graphs…