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
00023 #ifndef U_HIDE_DRAFT_API
00024
00031 enum ULocMatchFavorSubtag {
00038 ULOCMATCH_FAVOR_LANGUAGE,
00044 ULOCMATCH_FAVOR_SCRIPT
00045 };
00046 #ifndef U_IN_DOXYGEN
00047 typedef enum ULocMatchFavorSubtag ULocMatchFavorSubtag;
00048 #endif
00049
00057 enum ULocMatchDemotion {
00063 ULOCMATCH_DEMOTION_NONE,
00090 ULOCMATCH_DEMOTION_REGION
00091 };
00092 #ifndef U_IN_DOXYGEN
00093 typedef enum ULocMatchDemotion ULocMatchDemotion;
00094 #endif
00095
00096 struct UHashtable;
00097
00098 U_NAMESPACE_BEGIN
00099
00100 struct LSR;
00101
00102 class LocaleDistance;
00103 class LocaleLsrIterator;
00104 class UVector;
00105 class XLikelySubtags;
00106
00150 class U_COMMON_API LocaleMatcher : public UMemory {
00151 public:
00158 class U_COMMON_API Result : public UMemory {
00159 public:
00167 Result(Result &&src) U_NOEXCEPT;
00168
00174 ~Result();
00175
00183 Result &operator=(Result &&src) U_NOEXCEPT;
00184
00192 inline const Locale *getDesiredLocale() const { return desiredLocale; }
00193
00203 inline const Locale *getSupportedLocale() const { return supportedLocale; }
00204
00212 inline int32_t getDesiredIndex() const { return desiredIndex; }
00213
00224 inline int32_t getSupportedIndex() const { return supportedIndex; }
00225
00238 Locale makeResolvedLocale(UErrorCode &errorCode) const;
00239
00240 private:
00241 Result(const Locale *desired, const Locale *supported,
00242 int32_t desIndex, int32_t suppIndex, UBool owned) :
00243 desiredLocale(desired), supportedLocale(supported),
00244 desiredIndex(desIndex), supportedIndex(suppIndex),
00245 desiredIsOwned(owned) {}
00246
00247 Result(const Result &other) = delete;
00248 Result &operator=(const Result &other) = delete;
00249
00250 const Locale *desiredLocale;
00251 const Locale *supportedLocale;
00252 int32_t desiredIndex;
00253 int32_t supportedIndex;
00254 UBool desiredIsOwned;
00255
00256 friend class LocaleMatcher;
00257 };
00258
00266 class U_COMMON_API Builder : public UMemory {
00267 public:
00274 Builder() {}
00275
00283 Builder(Builder &&src) U_NOEXCEPT;
00284
00290 ~Builder();
00291
00299 Builder &operator=(Builder &&src) U_NOEXCEPT;
00300
00312 Builder &setSupportedLocalesFromListString(StringPiece locales);
00313
00323 Builder &setSupportedLocales(Locale::Iterator &locales);
00324
00338 template<typename Iter>
00339 Builder &setSupportedLocales(Iter begin, Iter end) {
00340 if (U_FAILURE(errorCode_)) { return *this; }
00341 clearSupportedLocales();
00342 while (begin != end) {
00343 addSupportedLocale(*begin++);
00344 }
00345 return *this;
00346 }
00347
00363 template<typename Iter, typename Conv>
00364 Builder &setSupportedLocalesViaConverter(Iter begin, Iter end, Conv converter) {
00365 if (U_FAILURE(errorCode_)) { return *this; }
00366 clearSupportedLocales();
00367 while (begin != end) {
00368 addSupportedLocale(converter(*begin++));
00369 }
00370 return *this;
00371 }
00372
00381 Builder &addSupportedLocale(const Locale &locale);
00382
00391 Builder &setDefaultLocale(const Locale *defaultLocale);
00392
00403 Builder &setFavorSubtag(ULocMatchFavorSubtag subtag);
00404
00413 Builder &setDemotionPerDesiredLocale(ULocMatchDemotion demotion);
00414
00425 UBool copyErrorTo(UErrorCode &outErrorCode) const;
00426
00437 LocaleMatcher build(UErrorCode &errorCode) const;
00438
00439 private:
00440 friend class LocaleMatcher;
00441
00442 Builder(const Builder &other) = delete;
00443 Builder &operator=(const Builder &other) = delete;
00444
00445 void clearSupportedLocales();
00446 bool ensureSupportedLocaleVector();
00447
00448 UErrorCode errorCode_ = U_ZERO_ERROR;
00449 UVector *supportedLocales_ = nullptr;
00450 int32_t thresholdDistance_ = -1;
00451 ULocMatchDemotion demotion_ = ULOCMATCH_DEMOTION_REGION;
00452 Locale *defaultLocale_ = nullptr;
00453 ULocMatchFavorSubtag favor_ = ULOCMATCH_FAVOR_LANGUAGE;
00454 };
00455
00456
00457
00464 LocaleMatcher(LocaleMatcher &&src) U_NOEXCEPT;
00465
00470 ~LocaleMatcher();
00471
00480 LocaleMatcher &operator=(LocaleMatcher &&src) U_NOEXCEPT;
00481
00492 const Locale *getBestMatch(const Locale &desiredLocale, UErrorCode &errorCode) const;
00493
00504 const Locale *getBestMatch(Locale::Iterator &desiredLocales, UErrorCode &errorCode) const;
00505
00520 const Locale *getBestMatchForListString(StringPiece desiredLocaleList, UErrorCode &errorCode) const;
00521
00534 Result getBestMatchResult(const Locale &desiredLocale, UErrorCode &errorCode) const;
00535
00548 Result getBestMatchResult(Locale::Iterator &desiredLocales, UErrorCode &errorCode) const;
00549
00550 #ifndef U_HIDE_INTERNAL_API
00551
00569 double internalMatch(const Locale &desired, const Locale &supported, UErrorCode &errorCode) const;
00570 #endif // U_HIDE_INTERNAL_API
00571
00572 private:
00573 LocaleMatcher(const Builder &builder, UErrorCode &errorCode);
00574 LocaleMatcher(const LocaleMatcher &other) = delete;
00575 LocaleMatcher &operator=(const LocaleMatcher &other) = delete;
00576
00577 int32_t getBestSuppIndex(LSR desiredLSR, LocaleLsrIterator *remainingIter, UErrorCode &errorCode) const;
00578
00579 const XLikelySubtags &likelySubtags;
00580 const LocaleDistance &localeDistance;
00581 int32_t thresholdDistance;
00582 int32_t demotionPerDesiredLocale;
00583 ULocMatchFavorSubtag favorSubtag;
00584
00585
00586 const Locale ** supportedLocales;
00587 LSR *lsrs;
00588 int32_t supportedLocalesLength;
00589
00590 UHashtable *supportedLsrToIndex;
00591
00592
00593 const LSR **supportedLSRs;
00594 int32_t *supportedIndexes;
00595 int32_t supportedLSRsLength;
00596 Locale *ownedDefaultLocale;
00597 const Locale *defaultLocale;
00598 int32_t defaultLocaleIndex;
00599 };
00600
00601 U_NAMESPACE_END
00602
00603 #endif // U_HIDE_DRAFT_API
00604 #endif // U_SHOW_CPLUSPLUS_API
00605 #endif // __LOCALEMATCHER_H__