00001
00002
00003
00004
00005
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) U_NOEXCEPT;
00202
00208 ~Result();
00209
00217 Result &operator=(Result &&src) U_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) U_NOEXCEPT;
00317
00323 ~Builder();
00324
00332 Builder &operator=(Builder &&src) U_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
00544
00551 LocaleMatcher(LocaleMatcher &&src) U_NOEXCEPT;
00552
00557 ~LocaleMatcher();
00558
00567 LocaleMatcher &operator=(LocaleMatcher &&src) U_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
00691 const Locale ** supportedLocales;
00692 LSR *lsrs;
00693 int32_t supportedLocalesLength;
00694
00695 UHashtable *supportedLsrToIndex;
00696
00697
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__