localematcher.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. // © 2019 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. // localematcher.h
  4. // created: 2019may08 Markus W. Scherer
  5. #ifndef __LOCALEMATCHER_H__
  6. #define __LOCALEMATCHER_H__
  7. #include "unicode/utypes.h"
  8. #if U_SHOW_CPLUSPLUS_API
  9. #include "unicode/locid.h"
  10. #include "unicode/stringpiece.h"
  11. #include "unicode/uobject.h"
  12. /**
  13. * \file
  14. * \brief C++ API: Locale matcher: User's desired locales vs. application's supported locales.
  15. */
  16. /**
  17. * Builder option for whether the language subtag or the script subtag is most important.
  18. *
  19. * @see LocaleMatcher::Builder#setFavorSubtag(ULocMatchFavorSubtag)
  20. * @stable ICU 65
  21. */
  22. enum ULocMatchFavorSubtag {
  23. /**
  24. * Language differences are most important, then script differences, then region differences.
  25. * (This is the default behavior.)
  26. *
  27. * @stable ICU 65
  28. */
  29. ULOCMATCH_FAVOR_LANGUAGE,
  30. /**
  31. * Makes script differences matter relatively more than language differences.
  32. *
  33. * @stable ICU 65
  34. */
  35. ULOCMATCH_FAVOR_SCRIPT
  36. };
  37. #ifndef U_IN_DOXYGEN
  38. typedef enum ULocMatchFavorSubtag ULocMatchFavorSubtag;
  39. #endif
  40. /**
  41. * Builder option for whether all desired locales are treated equally or
  42. * earlier ones are preferred.
  43. *
  44. * @see LocaleMatcher::Builder#setDemotionPerDesiredLocale(ULocMatchDemotion)
  45. * @stable ICU 65
  46. */
  47. enum ULocMatchDemotion {
  48. /**
  49. * All desired locales are treated equally.
  50. *
  51. * @stable ICU 65
  52. */
  53. ULOCMATCH_DEMOTION_NONE,
  54. /**
  55. * Earlier desired locales are preferred.
  56. *
  57. * <p>From each desired locale to the next,
  58. * the distance to any supported locale is increased by an additional amount
  59. * which is at least as large as most region mismatches.
  60. * A later desired locale has to have a better match with some supported locale
  61. * due to more than merely having the same region subtag.
  62. *
  63. * <p>For example: <code>Supported={en, sv} desired=[en-GB, sv]</code>
  64. * yields <code>Result(en-GB, en)</code> because
  65. * with the demotion of sv its perfect match is no better than
  66. * the region distance between the earlier desired locale en-GB and en=en-US.
  67. *
  68. * <p>Notes:
  69. * <ul>
  70. * <li>In some cases, language and/or script differences can be as small as
  71. * the typical region difference. (Example: sr-Latn vs. sr-Cyrl)
  72. * <li>It is possible for certain region differences to be larger than usual,
  73. * and larger than the demotion.
  74. * (As of CLDR 35 there is no such case, but
  75. * this is possible in future versions of the data.)
  76. * </ul>
  77. *
  78. * @stable ICU 65
  79. */
  80. ULOCMATCH_DEMOTION_REGION
  81. };
  82. #ifndef U_IN_DOXYGEN
  83. typedef enum ULocMatchDemotion ULocMatchDemotion;
  84. #endif
  85. /**
  86. * Builder option for whether to include or ignore one-way (fallback) match data.
  87. * The LocaleMatcher uses CLDR languageMatch data which includes fallback (oneway=true) entries.
  88. * Sometimes it is desirable to ignore those.
  89. *
  90. * <p>For example, consider a web application with the UI in a given language,
  91. * with a link to another, related web app.
  92. * The link should include the UI language, and the target server may also use
  93. * the client’s Accept-Language header data.
  94. * The target server has its own list of supported languages.
  95. * One may want to favor UI language consistency, that is,
  96. * if there is a decent match for the original UI language, we want to use it,
  97. * but not if it is merely a fallback.
  98. *
  99. * @see LocaleMatcher::Builder#setDirection(ULocMatchDirection)
  100. * @stable ICU 67
  101. */
  102. enum ULocMatchDirection {
  103. /**
  104. * Locale matching includes one-way matches such as Breton→French. (default)
  105. *
  106. * @stable ICU 67
  107. */
  108. ULOCMATCH_DIRECTION_WITH_ONE_WAY,
  109. /**
  110. * Locale matching limited to two-way matches including e.g. Danish↔Norwegian
  111. * but ignoring one-way matches.
  112. *
  113. * @stable ICU 67
  114. */
  115. ULOCMATCH_DIRECTION_ONLY_TWO_WAY
  116. };
  117. #ifndef U_IN_DOXYGEN
  118. typedef enum ULocMatchDirection ULocMatchDirection;
  119. #endif
  120. struct UHashtable;
  121. U_NAMESPACE_BEGIN
  122. struct LSR;
  123. class LocaleDistance;
  124. class LocaleLsrIterator;
  125. class UVector;
  126. class XLikelySubtags;
  127. /**
  128. * Immutable class that picks the best match between a user's desired locales and
  129. * an application's supported locales.
  130. * Movable but not copyable.
  131. *
  132. * <p>Example:
  133. * <pre>
  134. * UErrorCode errorCode = U_ZERO_ERROR;
  135. * LocaleMatcher matcher = LocaleMatcher::Builder().setSupportedLocales("fr, en-GB, en").build(errorCode);
  136. * Locale *bestSupported = matcher.getBestLocale(Locale.US, errorCode); // "en"
  137. * </pre>
  138. *
  139. * <p>A matcher takes into account when languages are close to one another,
  140. * such as Danish and Norwegian,
  141. * and when regional variants are close, like en-GB and en-AU as opposed to en-US.
  142. *
  143. * <p>If there are multiple supported locales with the same (language, script, region)
  144. * likely subtags, then the current implementation returns the first of those locales.
  145. * It ignores variant subtags (except for pseudolocale variants) and extensions.
  146. * This may change in future versions.
  147. *
  148. * <p>For example, the current implementation does not distinguish between
  149. * de, de-DE, de-Latn, de-1901, de-u-co-phonebk.
  150. *
  151. * <p>If you prefer one equivalent locale over another, then provide only the preferred one,
  152. * or place it earlier in the list of supported locales.
  153. *
  154. * <p>Otherwise, the order of supported locales may have no effect on the best-match results.
  155. * The current implementation compares each desired locale with supported locales
  156. * in the following order:
  157. * 1. Default locale, if supported;
  158. * 2. CLDR "paradigm locales" like en-GB and es-419;
  159. * 3. other supported locales.
  160. * This may change in future versions.
  161. *
  162. * <p>Often a product will just need one matcher instance, built with the languages
  163. * that it supports. However, it may want multiple instances with different
  164. * default languages based on additional information, such as the domain.
  165. *
  166. * <p>This class is not intended for public subclassing.
  167. *
  168. * @stable ICU 65
  169. */
  170. class U_COMMON_API LocaleMatcher : public UMemory {
  171. public:
  172. /**
  173. * Data for the best-matching pair of a desired and a supported locale.
  174. * Movable but not copyable.
  175. *
  176. * @stable ICU 65
  177. */
  178. class U_COMMON_API Result : public UMemory {
  179. public:
  180. /**
  181. * Move constructor; might modify the source.
  182. * This object will have the same contents that the source object had.
  183. *
  184. * @param src Result to move contents from.
  185. * @stable ICU 65
  186. */
  187. Result(Result &&src) noexcept;
  188. /**
  189. * Destructor.
  190. *
  191. * @stable ICU 65
  192. */
  193. ~Result();
  194. /**
  195. * Move assignment; might modify the source.
  196. * This object will have the same contents that the source object had.
  197. *
  198. * @param src Result to move contents from.
  199. * @stable ICU 65
  200. */
  201. Result &operator=(Result &&src) noexcept;
  202. /**
  203. * Returns the best-matching desired locale.
  204. * nullptr if the list of desired locales is empty or if none matched well enough.
  205. *
  206. * @return the best-matching desired locale, or nullptr.
  207. * @stable ICU 65
  208. */
  209. inline const Locale *getDesiredLocale() const { return desiredLocale; }
  210. /**
  211. * Returns the best-matching supported locale.
  212. * If none matched well enough, this is the default locale.
  213. * The default locale is nullptr if Builder::setNoDefaultLocale() was called,
  214. * or if the list of supported locales is empty and no explicit default locale is set.
  215. *
  216. * @return the best-matching supported locale, or nullptr.
  217. * @stable ICU 65
  218. */
  219. inline const Locale *getSupportedLocale() const { return supportedLocale; }
  220. /**
  221. * Returns the index of the best-matching desired locale in the input Iterable order.
  222. * -1 if the list of desired locales is empty or if none matched well enough.
  223. *
  224. * @return the index of the best-matching desired locale, or -1.
  225. * @stable ICU 65
  226. */
  227. inline int32_t getDesiredIndex() const { return desiredIndex; }
  228. /**
  229. * Returns the index of the best-matching supported locale in the
  230. * constructor’s or builder’s input order (“set” Collection plus “added” locales).
  231. * If the matcher was built from a locale list string, then the iteration order is that
  232. * of a LocalePriorityList built from the same string.
  233. * -1 if the list of supported locales is empty or if none matched well enough.
  234. *
  235. * @return the index of the best-matching supported locale, or -1.
  236. * @stable ICU 65
  237. */
  238. inline int32_t getSupportedIndex() const { return supportedIndex; }
  239. /**
  240. * Takes the best-matching supported locale and adds relevant fields of the
  241. * best-matching desired locale, such as the -t- and -u- extensions.
  242. * May replace some fields of the supported locale.
  243. * The result is the locale that should be used for date and number formatting, collation, etc.
  244. * Returns the root locale if getSupportedLocale() returns nullptr.
  245. *
  246. * <p>Example: desired=ar-SA-u-nu-latn, supported=ar-EG, resolved locale=ar-SA-u-nu-latn
  247. *
  248. * @return a locale combining the best-matching desired and supported locales.
  249. * @stable ICU 65
  250. */
  251. Locale makeResolvedLocale(UErrorCode &errorCode) const;
  252. private:
  253. Result(const Locale *desired, const Locale *supported,
  254. int32_t desIndex, int32_t suppIndex, UBool owned) :
  255. desiredLocale(desired), supportedLocale(supported),
  256. desiredIndex(desIndex), supportedIndex(suppIndex),
  257. desiredIsOwned(owned) {}
  258. Result(const Result &other) = delete;
  259. Result &operator=(const Result &other) = delete;
  260. const Locale *desiredLocale;
  261. const Locale *supportedLocale;
  262. int32_t desiredIndex;
  263. int32_t supportedIndex;
  264. UBool desiredIsOwned;
  265. friend class LocaleMatcher;
  266. };
  267. /**
  268. * LocaleMatcher builder.
  269. * Movable but not copyable.
  270. *
  271. * @stable ICU 65
  272. */
  273. class U_COMMON_API Builder : public UMemory {
  274. public:
  275. /**
  276. * Constructs a builder used in chaining parameters for building a LocaleMatcher.
  277. *
  278. * @return a new Builder object
  279. * @stable ICU 65
  280. */
  281. Builder() {}
  282. /**
  283. * Move constructor; might modify the source.
  284. * This builder will have the same contents that the source builder had.
  285. *
  286. * @param src Builder to move contents from.
  287. * @stable ICU 65
  288. */
  289. Builder(Builder &&src) noexcept;
  290. /**
  291. * Destructor.
  292. *
  293. * @stable ICU 65
  294. */
  295. ~Builder();
  296. /**
  297. * Move assignment; might modify the source.
  298. * This builder will have the same contents that the source builder had.
  299. *
  300. * @param src Builder to move contents from.
  301. * @stable ICU 65
  302. */
  303. Builder &operator=(Builder &&src) noexcept;
  304. /**
  305. * Parses an Accept-Language string
  306. * (<a href="https://tools.ietf.org/html/rfc2616#section-14.4">RFC 2616 Section 14.4</a>),
  307. * such as "af, en, fr;q=0.9", and sets the supported locales accordingly.
  308. * Allows whitespace in more places but does not allow "*".
  309. * Clears any previously set/added supported locales first.
  310. *
  311. * @param locales the Accept-Language string of locales to set
  312. * @return this Builder object
  313. * @stable ICU 65
  314. */
  315. Builder &setSupportedLocalesFromListString(StringPiece locales);
  316. /**
  317. * Copies the supported locales, preserving iteration order.
  318. * Clears any previously set/added supported locales first.
  319. * Duplicates are allowed, and are not removed.
  320. *
  321. * @param locales the list of locale
  322. * @return this Builder object
  323. * @stable ICU 65
  324. */
  325. Builder &setSupportedLocales(Locale::Iterator &locales);
  326. /**
  327. * Copies the supported locales from the begin/end range, preserving iteration order.
  328. * Clears any previously set/added supported locales first.
  329. * Duplicates are allowed, and are not removed.
  330. *
  331. * Each of the iterator parameter values must be an
  332. * input iterator whose value is convertible to const Locale &.
  333. *
  334. * @param begin Start of range.
  335. * @param end Exclusive end of range.
  336. * @return this Builder object
  337. * @stable ICU 65
  338. */
  339. template<typename Iter>
  340. Builder &setSupportedLocales(Iter begin, Iter end) {
  341. if (U_FAILURE(errorCode_)) { return *this; }
  342. clearSupportedLocales();
  343. while (begin != end) {
  344. addSupportedLocale(*begin++);
  345. }
  346. return *this;
  347. }
  348. /**
  349. * Copies the supported locales from the begin/end range, preserving iteration order.
  350. * Calls the converter to convert each *begin to a Locale or const Locale &.
  351. * Clears any previously set/added supported locales first.
  352. * Duplicates are allowed, and are not removed.
  353. *
  354. * Each of the iterator parameter values must be an
  355. * input iterator whose value is convertible to const Locale &.
  356. *
  357. * @param begin Start of range.
  358. * @param end Exclusive end of range.
  359. * @param converter Converter from *begin to const Locale & or compatible.
  360. * @return this Builder object
  361. * @stable ICU 65
  362. */
  363. template<typename Iter, typename Conv>
  364. Builder &setSupportedLocalesViaConverter(Iter begin, Iter end, Conv converter) {
  365. if (U_FAILURE(errorCode_)) { return *this; }
  366. clearSupportedLocales();
  367. while (begin != end) {
  368. addSupportedLocale(converter(*begin++));
  369. }
  370. return *this;
  371. }
  372. /**
  373. * Adds another supported locale.
  374. * Duplicates are allowed, and are not removed.
  375. *
  376. * @param locale another locale
  377. * @return this Builder object
  378. * @stable ICU 65
  379. */
  380. Builder &addSupportedLocale(const Locale &locale);
  381. /**
  382. * Sets no default locale.
  383. * There will be no explicit or implicit default locale.
  384. * If there is no good match, then the matcher will return nullptr for the
  385. * best supported locale.
  386. *
  387. * @stable ICU 68
  388. */
  389. Builder &setNoDefaultLocale();
  390. /**
  391. * Sets the default locale; if nullptr, or if it is not set explicitly,
  392. * then the first supported locale is used as the default locale.
  393. * There is no default locale at all (nullptr will be returned instead)
  394. * if setNoDefaultLocale() is called.
  395. *
  396. * @param defaultLocale the default locale (will be copied)
  397. * @return this Builder object
  398. * @stable ICU 65
  399. */
  400. Builder &setDefaultLocale(const Locale *defaultLocale);
  401. /**
  402. * If ULOCMATCH_FAVOR_SCRIPT, then the language differences are smaller than script
  403. * differences.
  404. * This is used in situations (such as maps) where
  405. * it is better to fall back to the same script than a similar language.
  406. *
  407. * @param subtag the subtag to favor
  408. * @return this Builder object
  409. * @stable ICU 65
  410. */
  411. Builder &setFavorSubtag(ULocMatchFavorSubtag subtag);
  412. /**
  413. * Option for whether all desired locales are treated equally or
  414. * earlier ones are preferred (this is the default).
  415. *
  416. * @param demotion the demotion per desired locale to set.
  417. * @return this Builder object
  418. * @stable ICU 65
  419. */
  420. Builder &setDemotionPerDesiredLocale(ULocMatchDemotion demotion);
  421. /**
  422. * Option for whether to include or ignore one-way (fallback) match data.
  423. * By default, they are included.
  424. *
  425. * @param matchDirection the match direction to set.
  426. * @return this Builder object
  427. * @stable ICU 67
  428. */
  429. Builder &setDirection(ULocMatchDirection matchDirection) {
  430. if (U_SUCCESS(errorCode_)) {
  431. direction_ = matchDirection;
  432. }
  433. return *this;
  434. }
  435. /**
  436. * Sets the maximum distance for an acceptable match.
  437. * The matcher will return a match for a pair of locales only if
  438. * they match at least as well as the pair given here.
  439. *
  440. * For example, setMaxDistance(en-US, en-GB) limits matches to ones where the
  441. * (desired, support) locales have a distance no greater than a region subtag difference.
  442. * This is much stricter than the CLDR default.
  443. *
  444. * The details of locale matching are subject to changes in
  445. * CLDR data and in the algorithm.
  446. * Specifying a maximum distance in relative terms via a sample pair of locales
  447. * insulates from changes that affect all distance metrics similarly,
  448. * but some changes will necessarily affect relative distances between
  449. * different pairs of locales.
  450. *
  451. * @param desired the desired locale for distance comparison.
  452. * @param supported the supported locale for distance comparison.
  453. * @return this Builder object
  454. * @stable ICU 68
  455. */
  456. Builder &setMaxDistance(const Locale &desired, const Locale &supported);
  457. /**
  458. * Sets the UErrorCode if an error occurred while setting parameters.
  459. * Preserves older error codes in the outErrorCode.
  460. *
  461. * @param outErrorCode Set to an error code if it does not contain one already
  462. * and an error occurred while setting parameters.
  463. * Otherwise unchanged.
  464. * @return true if U_FAILURE(outErrorCode)
  465. * @stable ICU 65
  466. */
  467. UBool copyErrorTo(UErrorCode &outErrorCode) const;
  468. /**
  469. * Builds and returns a new locale matcher.
  470. * This builder can continue to be used.
  471. *
  472. * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
  473. * or else the function returns immediately. Check for U_FAILURE()
  474. * on output or use with function chaining. (See User Guide for details.)
  475. * @return LocaleMatcher
  476. * @stable ICU 65
  477. */
  478. LocaleMatcher build(UErrorCode &errorCode) const;
  479. private:
  480. friend class LocaleMatcher;
  481. Builder(const Builder &other) = delete;
  482. Builder &operator=(const Builder &other) = delete;
  483. void clearSupportedLocales();
  484. bool ensureSupportedLocaleVector();
  485. UErrorCode errorCode_ = U_ZERO_ERROR;
  486. UVector *supportedLocales_ = nullptr;
  487. int32_t thresholdDistance_ = -1;
  488. ULocMatchDemotion demotion_ = ULOCMATCH_DEMOTION_REGION;
  489. Locale *defaultLocale_ = nullptr;
  490. bool withDefault_ = true;
  491. ULocMatchFavorSubtag favor_ = ULOCMATCH_FAVOR_LANGUAGE;
  492. ULocMatchDirection direction_ = ULOCMATCH_DIRECTION_WITH_ONE_WAY;
  493. Locale *maxDistanceDesired_ = nullptr;
  494. Locale *maxDistanceSupported_ = nullptr;
  495. };
  496. // FYI No public LocaleMatcher constructors in C++; use the Builder.
  497. /**
  498. * Move copy constructor; might modify the source.
  499. * This matcher will have the same settings that the source matcher had.
  500. * @param src source matcher
  501. * @stable ICU 65
  502. */
  503. LocaleMatcher(LocaleMatcher &&src) noexcept;
  504. /**
  505. * Destructor.
  506. * @stable ICU 65
  507. */
  508. ~LocaleMatcher();
  509. /**
  510. * Move assignment operator; might modify the source.
  511. * This matcher will have the same settings that the source matcher had.
  512. * The behavior is undefined if *this and src are the same object.
  513. * @param src source matcher
  514. * @return *this
  515. * @stable ICU 65
  516. */
  517. LocaleMatcher &operator=(LocaleMatcher &&src) noexcept;
  518. /**
  519. * Returns the supported locale which best matches the desired locale.
  520. *
  521. * @param desiredLocale Typically a user's language.
  522. * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
  523. * or else the function returns immediately. Check for U_FAILURE()
  524. * on output or use with function chaining. (See User Guide for details.)
  525. * @return the best-matching supported locale.
  526. * @stable ICU 65
  527. */
  528. const Locale *getBestMatch(const Locale &desiredLocale, UErrorCode &errorCode) const;
  529. /**
  530. * Returns the supported locale which best matches one of the desired locales.
  531. *
  532. * @param desiredLocales Typically a user's languages, in order of preference (descending).
  533. * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
  534. * or else the function returns immediately. Check for U_FAILURE()
  535. * on output or use with function chaining. (See User Guide for details.)
  536. * @return the best-matching supported locale.
  537. * @stable ICU 65
  538. */
  539. const Locale *getBestMatch(Locale::Iterator &desiredLocales, UErrorCode &errorCode) const;
  540. /**
  541. * Parses an Accept-Language string
  542. * (<a href="https://tools.ietf.org/html/rfc2616#section-14.4">RFC 2616 Section 14.4</a>),
  543. * such as "af, en, fr;q=0.9",
  544. * and returns the supported locale which best matches one of the desired locales.
  545. * Allows whitespace in more places but does not allow "*".
  546. *
  547. * @param desiredLocaleList Typically a user's languages, as an Accept-Language string.
  548. * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
  549. * or else the function returns immediately. Check for U_FAILURE()
  550. * on output or use with function chaining. (See User Guide for details.)
  551. * @return the best-matching supported locale.
  552. * @stable ICU 65
  553. */
  554. const Locale *getBestMatchForListString(StringPiece desiredLocaleList, UErrorCode &errorCode) const;
  555. /**
  556. * Returns the best match between the desired locale and the supported locales.
  557. * If the result's desired locale is not nullptr, then it is the address of the input locale.
  558. * It has not been cloned.
  559. *
  560. * @param desiredLocale Typically a user's language.
  561. * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
  562. * or else the function returns immediately. Check for U_FAILURE()
  563. * on output or use with function chaining. (See User Guide for details.)
  564. * @return the best-matching pair of the desired and a supported locale.
  565. * @stable ICU 65
  566. */
  567. Result getBestMatchResult(const Locale &desiredLocale, UErrorCode &errorCode) const;
  568. /**
  569. * Returns the best match between the desired and supported locales.
  570. * If the result's desired locale is not nullptr, then it is a clone of
  571. * the best-matching desired locale. The Result object owns the clone.
  572. *
  573. * @param desiredLocales Typically a user's languages, in order of preference (descending).
  574. * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
  575. * or else the function returns immediately. Check for U_FAILURE()
  576. * on output or use with function chaining. (See User Guide for details.)
  577. * @return the best-matching pair of a desired and a supported locale.
  578. * @stable ICU 65
  579. */
  580. Result getBestMatchResult(Locale::Iterator &desiredLocales, UErrorCode &errorCode) const;
  581. /**
  582. * Returns true if the pair of locales matches acceptably.
  583. * This is influenced by Builder options such as setDirection(), setFavorSubtag(),
  584. * and setMaxDistance().
  585. *
  586. * @param desired The desired locale.
  587. * @param supported The supported locale.
  588. * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
  589. * or else the function returns immediately. Check for U_FAILURE()
  590. * on output or use with function chaining. (See User Guide for details.)
  591. * @return true if the pair of locales matches acceptably.
  592. * @stable ICU 68
  593. */
  594. UBool isMatch(const Locale &desired, const Locale &supported, UErrorCode &errorCode) const;
  595. #ifndef U_HIDE_INTERNAL_API
  596. /**
  597. * Returns a fraction between 0 and 1, where 1 means that the languages are a
  598. * perfect match, and 0 means that they are completely different.
  599. *
  600. * <p>This is mostly an implementation detail, and the precise values may change over time.
  601. * The implementation may use either the maximized forms or the others ones, or both.
  602. * The implementation may or may not rely on the forms to be consistent with each other.
  603. *
  604. * <p>Callers should construct and use a matcher rather than match pairs of locales directly.
  605. *
  606. * @param desired Desired locale.
  607. * @param supported Supported locale.
  608. * @param errorCode ICU error code. Its input value must pass the U_SUCCESS() test,
  609. * or else the function returns immediately. Check for U_FAILURE()
  610. * on output or use with function chaining. (See User Guide for details.)
  611. * @return value between 0 and 1, inclusive.
  612. * @internal (has a known user)
  613. */
  614. double internalMatch(const Locale &desired, const Locale &supported, UErrorCode &errorCode) const;
  615. #endif // U_HIDE_INTERNAL_API
  616. private:
  617. LocaleMatcher(const Builder &builder, UErrorCode &errorCode);
  618. LocaleMatcher(const LocaleMatcher &other) = delete;
  619. LocaleMatcher &operator=(const LocaleMatcher &other) = delete;
  620. int32_t putIfAbsent(const LSR &lsr, int32_t i, int32_t suppLength, UErrorCode &errorCode);
  621. int32_t getBestSuppIndex(LSR desiredLSR, LocaleLsrIterator *remainingIter, UErrorCode &errorCode) const;
  622. const XLikelySubtags &likelySubtags;
  623. const LocaleDistance &localeDistance;
  624. int32_t thresholdDistance;
  625. int32_t demotionPerDesiredLocale;
  626. ULocMatchFavorSubtag favorSubtag;
  627. ULocMatchDirection direction;
  628. // These are in input order.
  629. const Locale ** supportedLocales;
  630. LSR *lsrs;
  631. int32_t supportedLocalesLength;
  632. // These are in preference order: 1. Default locale 2. paradigm locales 3. others.
  633. UHashtable *supportedLsrToIndex; // Map<LSR, Integer>
  634. // Array versions of the supportedLsrToIndex keys and values.
  635. // The distance lookup loops over the supportedLSRs and returns the index of the best match.
  636. const LSR **supportedLSRs;
  637. int32_t *supportedIndexes;
  638. int32_t supportedLSRsLength;
  639. Locale *ownedDefaultLocale;
  640. const Locale *defaultLocale;
  641. };
  642. U_NAMESPACE_END
  643. #endif // U_SHOW_CPLUSPLUS_API
  644. #endif // __LOCALEMATCHER_H__