|
ICU 73.2
73.2
|
00001 // © 2018 and later: Unicode, Inc. and others. 00002 // License & terms of use: http://www.unicode.org/copyright.html 00003 00004 #ifndef __NUMBERRANGEFORMATTER_H__ 00005 #define __NUMBERRANGEFORMATTER_H__ 00006 00007 #include "unicode/utypes.h" 00008 00009 #if U_SHOW_CPLUSPLUS_API 00010 00011 #if !UCONFIG_NO_FORMATTING 00012 00013 #include <atomic> 00014 #include "unicode/appendable.h" 00015 #include "unicode/fieldpos.h" 00016 #include "unicode/formattedvalue.h" 00017 #include "unicode/fpositer.h" 00018 #include "unicode/numberformatter.h" 00019 #include "unicode/unumberrangeformatter.h" 00020 00048 U_NAMESPACE_BEGIN 00049 00050 // Forward declarations: 00051 class PluralRules; 00052 00053 namespace number { // icu::number 00054 00055 // Forward declarations: 00056 class UnlocalizedNumberRangeFormatter; 00057 class LocalizedNumberRangeFormatter; 00058 class FormattedNumberRange; 00059 00060 namespace impl { 00061 00062 // Forward declarations: 00063 struct RangeMacroProps; 00064 class DecimalQuantity; 00065 class UFormattedNumberRangeData; 00066 class NumberRangeFormatterImpl; 00067 struct UFormattedNumberRangeImpl; 00068 00069 } // namespace impl 00070 00076 #if U_PLATFORM == U_PF_WINDOWS && !defined(U_IN_DOXYGEN) && !defined(U_STATIC_IMPLEMENTATION) 00077 } // namespace icu::number 00078 U_NAMESPACE_END 00079 00080 template struct U_I18N_API std::atomic< U_NAMESPACE_QUALIFIER number::impl::NumberRangeFormatterImpl*>; 00081 00082 U_NAMESPACE_BEGIN 00083 namespace number { // icu::number 00084 #endif 00085 00087 // Other helper classes would go here, but there are none. 00088 00089 namespace impl { // icu::number::impl 00090 00091 // Do not enclose entire MacroProps with #ifndef U_HIDE_INTERNAL_API, needed for a protected field 00093 struct U_I18N_API RangeMacroProps : public UMemory { 00095 UnlocalizedNumberFormatter formatter1; // = NumberFormatter::with(); 00096 00098 UnlocalizedNumberFormatter formatter2; // = NumberFormatter::with(); 00099 00101 bool singleFormatter = true; 00102 00104 UNumberRangeCollapse collapse = UNUM_RANGE_COLLAPSE_AUTO; 00105 00107 UNumberRangeIdentityFallback identityFallback = UNUM_IDENTITY_FALLBACK_APPROXIMATELY; 00108 00110 Locale locale; 00111 00112 // NOTE: Uses default copy and move constructors. 00113 00118 bool copyErrorTo(UErrorCode &status) const { 00119 return formatter1.copyErrorTo(status) || formatter2.copyErrorTo(status); 00120 } 00121 }; 00122 00123 } // namespace impl 00124 00130 template<typename Derived> 00131 class U_I18N_API NumberRangeFormatterSettings { 00132 public: 00145 Derived numberFormatterBoth(const UnlocalizedNumberFormatter &formatter) const &; 00146 00156 Derived numberFormatterBoth(const UnlocalizedNumberFormatter &formatter) &&; 00157 00167 Derived numberFormatterBoth(UnlocalizedNumberFormatter &&formatter) const &; 00168 00178 Derived numberFormatterBoth(UnlocalizedNumberFormatter &&formatter) &&; 00179 00191 Derived numberFormatterFirst(const UnlocalizedNumberFormatter &formatterFirst) const &; 00192 00202 Derived numberFormatterFirst(const UnlocalizedNumberFormatter &formatterFirst) &&; 00203 00213 Derived numberFormatterFirst(UnlocalizedNumberFormatter &&formatterFirst) const &; 00214 00224 Derived numberFormatterFirst(UnlocalizedNumberFormatter &&formatterFirst) &&; 00225 00237 Derived numberFormatterSecond(const UnlocalizedNumberFormatter &formatterSecond) const &; 00238 00248 Derived numberFormatterSecond(const UnlocalizedNumberFormatter &formatterSecond) &&; 00249 00259 Derived numberFormatterSecond(UnlocalizedNumberFormatter &&formatterSecond) const &; 00260 00270 Derived numberFormatterSecond(UnlocalizedNumberFormatter &&formatterSecond) &&; 00271 00289 Derived collapse(UNumberRangeCollapse collapse) const &; 00290 00300 Derived collapse(UNumberRangeCollapse collapse) &&; 00301 00322 Derived identityFallback(UNumberRangeIdentityFallback identityFallback) const &; 00323 00333 Derived identityFallback(UNumberRangeIdentityFallback identityFallback) &&; 00334 00346 LocalPointer<Derived> clone() const &; 00347 00355 LocalPointer<Derived> clone() &&; 00356 00363 UBool copyErrorTo(UErrorCode &outErrorCode) const { 00364 if (U_FAILURE(outErrorCode)) { 00365 // Do not overwrite the older error code 00366 return true; 00367 } 00368 fMacros.copyErrorTo(outErrorCode); 00369 return U_FAILURE(outErrorCode); 00370 } 00371 00372 // NOTE: Uses default copy and move constructors. 00373 00374 private: 00375 impl::RangeMacroProps fMacros; 00376 00377 // Don't construct me directly! Use (Un)LocalizedNumberFormatter. 00378 NumberRangeFormatterSettings() = default; 00379 00380 friend class LocalizedNumberRangeFormatter; 00381 friend class UnlocalizedNumberRangeFormatter; 00382 }; 00383 00384 // Explicit instantiations in source/i18n/numrange_fluent.cpp. 00385 // (MSVC treats imports/exports of explicit instantiations differently.) 00386 #ifndef _MSC_VER 00387 extern template class NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>; 00388 extern template class NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>; 00389 #endif 00390 00399 class U_I18N_API UnlocalizedNumberRangeFormatter 00400 : public NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>, public UMemory { 00401 00402 public: 00412 LocalizedNumberRangeFormatter locale(const icu::Locale &locale) const &; 00413 00423 LocalizedNumberRangeFormatter locale(const icu::Locale &locale) &&; 00424 00430 UnlocalizedNumberRangeFormatter() = default; 00431 00436 UnlocalizedNumberRangeFormatter(const UnlocalizedNumberRangeFormatter &other); 00437 00443 UnlocalizedNumberRangeFormatter(UnlocalizedNumberRangeFormatter&& src) noexcept; 00444 00449 UnlocalizedNumberRangeFormatter& operator=(const UnlocalizedNumberRangeFormatter& other); 00450 00456 UnlocalizedNumberRangeFormatter& operator=(UnlocalizedNumberRangeFormatter&& src) noexcept; 00457 00458 private: 00459 explicit UnlocalizedNumberRangeFormatter( 00460 const NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>& other); 00461 00462 explicit UnlocalizedNumberRangeFormatter( 00463 NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>&& src) noexcept; 00464 00465 // To give the fluent setters access to this class's constructor: 00466 friend class NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>; 00467 00468 // To give NumberRangeFormatter::with() access to this class's constructor: 00469 friend class NumberRangeFormatter; 00470 }; 00471 00480 class U_I18N_API LocalizedNumberRangeFormatter 00481 : public NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>, public UMemory { 00482 public: 00496 FormattedNumberRange formatFormattableRange( 00497 const Formattable& first, const Formattable& second, UErrorCode& status) const; 00498 00504 LocalizedNumberRangeFormatter() = default; 00505 00510 LocalizedNumberRangeFormatter(const LocalizedNumberRangeFormatter &other); 00511 00517 LocalizedNumberRangeFormatter(LocalizedNumberRangeFormatter&& src) noexcept; 00518 00523 LocalizedNumberRangeFormatter& operator=(const LocalizedNumberRangeFormatter& other); 00524 00530 LocalizedNumberRangeFormatter& operator=(LocalizedNumberRangeFormatter&& src) noexcept; 00531 00532 #ifndef U_HIDE_INTERNAL_API 00533 00544 void formatImpl(impl::UFormattedNumberRangeData& results, bool equalBeforeRounding, 00545 UErrorCode& status) const; 00546 00547 #endif /* U_HIDE_INTERNAL_API */ 00548 00553 ~LocalizedNumberRangeFormatter(); 00554 00555 private: 00556 std::atomic<impl::NumberRangeFormatterImpl*> fAtomicFormatter = {}; 00557 00558 const impl::NumberRangeFormatterImpl* getFormatter(UErrorCode& stauts) const; 00559 00560 explicit LocalizedNumberRangeFormatter( 00561 const NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>& other); 00562 00563 explicit LocalizedNumberRangeFormatter( 00564 NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>&& src) noexcept; 00565 00566 LocalizedNumberRangeFormatter(const impl::RangeMacroProps ¯os, const Locale &locale); 00567 00568 LocalizedNumberRangeFormatter(impl::RangeMacroProps &¯os, const Locale &locale); 00569 00570 // To give the fluent setters access to this class's constructor: 00571 friend class NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>; 00572 friend class NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>; 00573 00574 // To give UnlocalizedNumberRangeFormatter::locale() access to this class's constructor: 00575 friend class UnlocalizedNumberRangeFormatter; 00576 }; 00577 00586 class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue { 00587 public: 00588 // Copybrief: this method is older than the parent method 00596 UnicodeString toString(UErrorCode& status) const override; 00597 00598 // Copydoc: this method is new in ICU 64 00600 UnicodeString toTempString(UErrorCode& status) const override; 00601 00602 // Copybrief: this method is older than the parent method 00610 Appendable &appendTo(Appendable &appendable, UErrorCode& status) const override; 00611 00612 // Copydoc: this method is new in ICU 64 00614 UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const override; 00615 00635 template<typename StringClass> 00636 inline std::pair<StringClass, StringClass> getDecimalNumbers(UErrorCode& status) const; 00637 00647 UNumberRangeIdentityResult getIdentityResult(UErrorCode& status) const; 00648 00653 FormattedNumberRange() 00654 : fData(nullptr), fErrorCode(U_INVALID_STATE_ERROR) {} 00655 00659 FormattedNumberRange(const FormattedNumberRange&) = delete; 00660 00664 FormattedNumberRange& operator=(const FormattedNumberRange&) = delete; 00665 00671 FormattedNumberRange(FormattedNumberRange&& src) noexcept; 00672 00678 FormattedNumberRange& operator=(FormattedNumberRange&& src) noexcept; 00679 00684 ~FormattedNumberRange(); 00685 00686 private: 00687 // Can't use LocalPointer because UFormattedNumberRangeData is forward-declared 00688 const impl::UFormattedNumberRangeData *fData; 00689 00690 // Error code for the terminal methods 00691 UErrorCode fErrorCode; 00692 00696 explicit FormattedNumberRange(impl::UFormattedNumberRangeData *results) 00697 : fData(results), fErrorCode(U_ZERO_ERROR) {} 00698 00699 explicit FormattedNumberRange(UErrorCode errorCode) 00700 : fData(nullptr), fErrorCode(errorCode) {} 00701 00702 void getDecimalNumbers(ByteSink& sink1, ByteSink& sink2, UErrorCode& status) const; 00703 00704 const impl::UFormattedNumberRangeData* getData(UErrorCode& status) const; 00705 00706 // To allow PluralRules to access the underlying data 00707 friend class ::icu::PluralRules; 00708 00709 // To give LocalizedNumberRangeFormatter format methods access to this class's constructor: 00710 friend class LocalizedNumberRangeFormatter; 00711 00712 // To give C API access to internals 00713 friend struct impl::UFormattedNumberRangeImpl; 00714 }; 00715 00716 // inline impl of @stable ICU 68 method 00717 template<typename StringClass> 00718 std::pair<StringClass, StringClass> FormattedNumberRange::getDecimalNumbers(UErrorCode& status) const { 00719 StringClass str1; 00720 StringClass str2; 00721 StringByteSink<StringClass> sink1(&str1); 00722 StringByteSink<StringClass> sink2(&str2); 00723 getDecimalNumbers(sink1, sink2, status); 00724 return std::make_pair(str1, str2); 00725 } 00726 00732 class U_I18N_API NumberRangeFormatter final { 00733 public: 00741 static UnlocalizedNumberRangeFormatter with(); 00742 00752 static LocalizedNumberRangeFormatter withLocale(const Locale &locale); 00753 00757 NumberRangeFormatter() = delete; 00758 }; 00759 00760 } // namespace number 00761 U_NAMESPACE_END 00762 00763 #endif /* #if !UCONFIG_NO_FORMATTING */ 00764 00765 #endif /* U_SHOW_CPLUSPLUS_API */ 00766 00767 #endif // __NUMBERRANGEFORMATTER_H__ 00768
1.7.6.1