localematcher.h 27 KB

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