annotate CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/include/unicode/localematcher.h @ 69:33d812a61356

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