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