ICU 73.2  73.2
localematcher.h
Go to the documentation of this file.
00001 // © 2019 and later: Unicode, Inc. and others.
00002 // License & terms of use: http://www.unicode.org/copyright.html
00003 
00004 // localematcher.h
00005 // created: 2019may08 Markus W. Scherer
00006 
00007 #ifndef __LOCALEMATCHER_H__
00008 #define __LOCALEMATCHER_H__
00009 
00010 #include "unicode/utypes.h"
00011 
00012 #if U_SHOW_CPLUSPLUS_API
00013 
00014 #include "unicode/locid.h"
00015 #include "unicode/stringpiece.h"
00016 #include "unicode/uobject.h"
00017 
00029 enum ULocMatchFavorSubtag {
00036     ULOCMATCH_FAVOR_LANGUAGE,
00042     ULOCMATCH_FAVOR_SCRIPT
00043 };
00044 #ifndef U_IN_DOXYGEN
00045 typedef enum ULocMatchFavorSubtag ULocMatchFavorSubtag;
00046 #endif
00047 
00055 enum ULocMatchDemotion {
00061     ULOCMATCH_DEMOTION_NONE,
00088     ULOCMATCH_DEMOTION_REGION
00089 };
00090 #ifndef U_IN_DOXYGEN
00091 typedef enum ULocMatchDemotion ULocMatchDemotion;
00092 #endif
00093 
00111 enum ULocMatchDirection {
00117     ULOCMATCH_DIRECTION_WITH_ONE_WAY,
00124     ULOCMATCH_DIRECTION_ONLY_TWO_WAY
00125 };
00126 #ifndef U_IN_DOXYGEN
00127 typedef enum ULocMatchDirection ULocMatchDirection;
00128 #endif
00129 
00130 struct UHashtable;
00131 
00132 U_NAMESPACE_BEGIN
00133 
00134 struct LSR;
00135 
00136 class LocaleDistance;
00137 class LocaleLsrIterator;
00138 class UVector;
00139 class XLikelySubtags;
00140 
00184 class U_COMMON_API LocaleMatcher : public UMemory {
00185 public:
00192     class U_COMMON_API Result : public UMemory {
00193     public:
00201         Result(Result &&src) noexcept;
00202 
00208         ~Result();
00209 
00217         Result &operator=(Result &&src) noexcept;
00218 
00226         inline const Locale *getDesiredLocale() const { return desiredLocale; }
00227 
00237         inline const Locale *getSupportedLocale() const { return supportedLocale; }
00238 
00246         inline int32_t getDesiredIndex() const { return desiredIndex; }
00247 
00258         inline int32_t getSupportedIndex() const { return supportedIndex; }
00259 
00272         Locale makeResolvedLocale(UErrorCode &errorCode) const;
00273 
00274     private:
00275         Result(const Locale *desired, const Locale *supported,
00276                int32_t desIndex, int32_t suppIndex, UBool owned) :
00277                 desiredLocale(desired), supportedLocale(supported),
00278                 desiredIndex(desIndex), supportedIndex(suppIndex),
00279                 desiredIsOwned(owned) {}
00280 
00281         Result(const Result &other) = delete;
00282         Result &operator=(const Result &other) = delete;
00283 
00284         const Locale *desiredLocale;
00285         const Locale *supportedLocale;
00286         int32_t desiredIndex;
00287         int32_t supportedIndex;
00288         UBool desiredIsOwned;
00289 
00290         friend class LocaleMatcher;
00291     };
00292 
00299     class U_COMMON_API Builder : public UMemory {
00300     public:
00307         Builder() {}
00308 
00316         Builder(Builder &&src) noexcept;
00317 
00323         ~Builder();
00324 
00332         Builder &operator=(Builder &&src) noexcept;
00333 
00345         Builder &setSupportedLocalesFromListString(StringPiece locales);
00346 
00356         Builder &setSupportedLocales(Locale::Iterator &locales);
00357 
00371         template<typename Iter>
00372         Builder &setSupportedLocales(Iter begin, Iter end) {
00373             if (U_FAILURE(errorCode_)) { return *this; }
00374             clearSupportedLocales();
00375             while (begin != end) {
00376                 addSupportedLocale(*begin++);
00377             }
00378             return *this;
00379         }
00380 
00396         template<typename Iter, typename Conv>
00397         Builder &setSupportedLocalesViaConverter(Iter begin, Iter end, Conv converter) {
00398             if (U_FAILURE(errorCode_)) { return *this; }
00399             clearSupportedLocales();
00400             while (begin != end) {
00401                 addSupportedLocale(converter(*begin++));
00402             }
00403             return *this;
00404         }
00405 
00414         Builder &addSupportedLocale(const Locale &locale);
00415 
00424         Builder &setNoDefaultLocale();
00425 
00436         Builder &setDefaultLocale(const Locale *defaultLocale);
00437 
00448         Builder &setFavorSubtag(ULocMatchFavorSubtag subtag);
00449 
00458         Builder &setDemotionPerDesiredLocale(ULocMatchDemotion demotion);
00459 
00468         Builder &setDirection(ULocMatchDirection matchDirection) {
00469             if (U_SUCCESS(errorCode_)) {
00470                 direction_ = matchDirection;
00471             }
00472             return *this;
00473         }
00474 
00496         Builder &setMaxDistance(const Locale &desired, const Locale &supported);
00497 
00508         UBool copyErrorTo(UErrorCode &outErrorCode) const;
00509 
00520         LocaleMatcher build(UErrorCode &errorCode) const;
00521 
00522     private:
00523         friend class LocaleMatcher;
00524 
00525         Builder(const Builder &other) = delete;
00526         Builder &operator=(const Builder &other) = delete;
00527 
00528         void clearSupportedLocales();
00529         bool ensureSupportedLocaleVector();
00530 
00531         UErrorCode errorCode_ = U_ZERO_ERROR;
00532         UVector *supportedLocales_ = nullptr;
00533         int32_t thresholdDistance_ = -1;
00534         ULocMatchDemotion demotion_ = ULOCMATCH_DEMOTION_REGION;
00535         Locale *defaultLocale_ = nullptr;
00536         bool withDefault_ = true;
00537         ULocMatchFavorSubtag favor_ = ULOCMATCH_FAVOR_LANGUAGE;
00538         ULocMatchDirection direction_ = ULOCMATCH_DIRECTION_WITH_ONE_WAY;
00539         Locale *maxDistanceDesired_ = nullptr;
00540         Locale *maxDistanceSupported_ = nullptr;
00541     };
00542 
00543     // FYI No public LocaleMatcher constructors in C++; use the Builder.
00544 
00551     LocaleMatcher(LocaleMatcher &&src) noexcept;
00552 
00557     ~LocaleMatcher();
00558 
00567     LocaleMatcher &operator=(LocaleMatcher &&src) noexcept;
00568 
00579     const Locale *getBestMatch(const Locale &desiredLocale, UErrorCode &errorCode) const;
00580 
00591     const Locale *getBestMatch(Locale::Iterator &desiredLocales, UErrorCode &errorCode) const;
00592 
00607     const Locale *getBestMatchForListString(StringPiece desiredLocaleList, UErrorCode &errorCode) const;
00608 
00621     Result getBestMatchResult(const Locale &desiredLocale, UErrorCode &errorCode) const;
00622 
00635     Result getBestMatchResult(Locale::Iterator &desiredLocales, UErrorCode &errorCode) const;
00636 
00650     UBool isMatch(const Locale &desired, const Locale &supported, UErrorCode &errorCode) const;
00651 
00652 #ifndef U_HIDE_INTERNAL_API
00653 
00671     double internalMatch(const Locale &desired, const Locale &supported, UErrorCode &errorCode) const;
00672 #endif  // U_HIDE_INTERNAL_API
00673 
00674 private:
00675     LocaleMatcher(const Builder &builder, UErrorCode &errorCode);
00676     LocaleMatcher(const LocaleMatcher &other) = delete;
00677     LocaleMatcher &operator=(const LocaleMatcher &other) = delete;
00678 
00679     int32_t putIfAbsent(const LSR &lsr, int32_t i, int32_t suppLength, UErrorCode &errorCode);
00680 
00681     int32_t getBestSuppIndex(LSR desiredLSR, LocaleLsrIterator *remainingIter, UErrorCode &errorCode) const;
00682 
00683     const XLikelySubtags &likelySubtags;
00684     const LocaleDistance &localeDistance;
00685     int32_t thresholdDistance;
00686     int32_t demotionPerDesiredLocale;
00687     ULocMatchFavorSubtag favorSubtag;
00688     ULocMatchDirection direction;
00689 
00690     // These are in input order.
00691     const Locale ** supportedLocales;
00692     LSR *lsrs;
00693     int32_t supportedLocalesLength;
00694     // These are in preference order: 1. Default locale 2. paradigm locales 3. others.
00695     UHashtable *supportedLsrToIndex;  // Map<LSR, Integer>
00696     // Array versions of the supportedLsrToIndex keys and values.
00697     // The distance lookup loops over the supportedLSRs and returns the index of the best match.
00698     const LSR **supportedLSRs;
00699     int32_t *supportedIndexes;
00700     int32_t supportedLSRsLength;
00701     Locale *ownedDefaultLocale;
00702     const Locale *defaultLocale;
00703 };
00704 
00705 U_NAMESPACE_END
00706 
00707 #endif  // U_SHOW_CPLUSPLUS_API
00708 #endif  // __LOCALEMATCHER_H__