xref: /aosp_15_r20/external/icu/libicu/cts_headers/unicode/localematcher.h (revision 0e209d3975ff4a8c132096b14b0e9364a753506e)
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