ICU 73.2  73.2
numberrangeformatter.h
Go to the documentation of this file.
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 &macros, const Locale &locale);
00567 
00568     LocalizedNumberRangeFormatter(impl::RangeMacroProps &&macros, 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