| 201 | |
| 202 | template <typename DFA> |
| 203 | pair<bool, bool> MatchFeatureByNameAndType(EditableMapObject const & emo, SearchTrieRequest<DFA> const & request) |
| 204 | { |
| 205 | auto const & th = emo.GetTypes(); |
| 206 | |
| 207 | pair<bool, bool> matchedByType = MatchesByType(th, request.m_categories); |
| 208 | |
| 209 | // Exactly matched by type. |
| 210 | if (matchedByType.second) |
| 211 | return {true, true}; |
| 212 | |
| 213 | pair<bool, bool> matchedByName = {false, false}; |
| 214 | emo.GetNameMultilang().ForEach([&](int8_t lang, string_view name) |
| 215 | { |
| 216 | if (name.empty() || !request.HasLang(lang)) |
| 217 | return base::ControlFlow::Continue; |
| 218 | |
| 219 | auto const tokens = NormalizeAndTokenizeString(name); |
| 220 | auto const matched = MatchesByName(tokens, request.m_names); |
| 221 | matchedByName = {matchedByName.first || matched.first, matchedByName.second || matched.second}; |
| 222 | if (!matchedByName.second) |
| 223 | return base::ControlFlow::Continue; |
| 224 | |
| 225 | return base::ControlFlow::Break; |
| 226 | }); |
| 227 | |
| 228 | return {matchedByType.first || matchedByName.first, matchedByType.second || matchedByName.second}; |
| 229 | } |
| 230 | |
| 231 | bool MatchFeatureByPostcode(EditableMapObject const & emo, TokenSlice const & slice) |
| 232 | { |
no test coverage detected