If first 2 (1 for short types like "building") components of pre-matched types are the same, then leave only the longest types (there could be a few of them). Equal arity types are kept. - highway-primary-bridge is left while highway-primary is removed; - building-garages is left while building is removed; - amenity-parking-underground-fee is left while amenity-parking and amenity-parking-fee is r
| 365 | // - amenity-parking-underground-fee is left while amenity-parking and amenity-parking-fee is removed; |
| 366 | // - both amenity-charging_station-motorcar and amenity-charging_station-bicycle are left; |
| 367 | void LeaveLongestTypes(std::vector<generator::TypeStrings> & matchedTypes) |
| 368 | { |
| 369 | // Prevents types, that either have subtypes or are subtypes, from being removed |
| 370 | auto subtypes = ftypes::Subtypes::Instance(); |
| 371 | auto const areSubtypeRelatedTypes = [subtypes](auto const & lhs, auto const & rhs) |
| 372 | { return subtypes.IsTypeWithSubtypesOrSubtype(lhs) && subtypes.IsTypeWithSubtypesOrSubtype(rhs); }; |
| 373 | auto const isBetterBecauseOfSubtypeRelation = [subtypes](auto const & lhs, auto const & rhs) -> std::optional<bool> |
| 374 | { |
| 375 | bool const lhsIsTypeWithSubtypesOrSubtype = subtypes.IsTypeWithSubtypesOrSubtype(lhs); |
| 376 | bool const rhsIsTypeWithSubtypesOrSubtype = subtypes.IsTypeWithSubtypesOrSubtype(rhs); |
| 377 | if (lhsIsTypeWithSubtypesOrSubtype && !rhsIsTypeWithSubtypesOrSubtype) |
| 378 | return true; |
| 379 | else if (!lhsIsTypeWithSubtypesOrSubtype && rhsIsTypeWithSubtypesOrSubtype) |
| 380 | return false; |
| 381 | |
| 382 | return subtypes.ComparisonResultBasedOnTypeRelation(lhs, rhs); |
| 383 | }; |
| 384 | |
| 385 | auto const equalPrefix = [](auto const & lhs, auto const & rhs) |
| 386 | { |
| 387 | size_t const prefixSz = std::min(lhs.size(), rhs.size()); |
| 388 | return equal(lhs.begin(), lhs.begin() + std::min(size_t(2), prefixSz), rhs.begin()); |
| 389 | }; |
| 390 | |
| 391 | auto const isBetter = [&equalPrefix, &isBetterBecauseOfSubtypeRelation](auto const & lhs, auto const & rhs) |
| 392 | { |
| 393 | std::optional<bool> const isBetterBecauseOfSubtypeRelationResult = isBetterBecauseOfSubtypeRelation(lhs, rhs); |
| 394 | if (isBetterBecauseOfSubtypeRelationResult.has_value()) |
| 395 | return isBetterBecauseOfSubtypeRelationResult.value(); |
| 396 | |
| 397 | if (equalPrefix(lhs, rhs)) |
| 398 | { |
| 399 | // Longest type is better. |
| 400 | if (lhs.size() != rhs.size()) |
| 401 | return lhs.size() > rhs.size(); |
| 402 | } |
| 403 | |
| 404 | return lhs < rhs; |
| 405 | }; |
| 406 | |
| 407 | // `true` means the second one will be removed, because being equal means it isn't unique and the first one is more |
| 408 | // important |
| 409 | auto const isEqual = [&equalPrefix, &areSubtypeRelatedTypes](auto const & lhs, auto const & rhs) |
| 410 | { |
| 411 | if (equalPrefix(lhs, rhs)) |
| 412 | { |
| 413 | // Keep longest type only |
| 414 | if (lhs.size() != rhs.size()) |
| 415 | return !areSubtypeRelatedTypes(lhs, rhs); |
| 416 | |
| 417 | return lhs == rhs; |
| 418 | } |
| 419 | return false; |
| 420 | }; |
| 421 | |
| 422 | base::SortUnique(matchedTypes, isBetter, isEqual); |
| 423 | } |
| 424 |
no test coverage detected