Home | History | Annotate | Download | only in i18n
      1 //  2017 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 
      4 #include "unicode/utypes.h"
      5 
      6 #if !UCONFIG_NO_FORMATTING && !UPRV_INCOMPLETE_CPP11_SUPPORT
      7 #ifndef __NUMBER_UTILS_H__
      8 #define __NUMBER_UTILS_H__
      9 
     10 #include "unicode/numberformatter.h"
     11 #include "number_types.h"
     12 #include "number_decimalquantity.h"
     13 #include "number_scientific.h"
     14 #include "number_patternstring.h"
     15 #include "number_modifiers.h"
     16 
     17 U_NAMESPACE_BEGIN namespace number {
     18 namespace impl {
     19 
     20 class UnicodeStringCharSequence : public CharSequence {
     21   public:
     22     explicit UnicodeStringCharSequence(const UnicodeString &other) {
     23         fStr = other;
     24     }
     25 
     26     ~UnicodeStringCharSequence() U_OVERRIDE = default;
     27 
     28     int32_t length() const U_OVERRIDE {
     29         return fStr.length();
     30     }
     31 
     32     char16_t charAt(int32_t index) const U_OVERRIDE {
     33         return fStr.charAt(index);
     34     }
     35 
     36     UChar32 codePointAt(int32_t index) const U_OVERRIDE {
     37         return fStr.char32At(index);
     38     }
     39 
     40     UnicodeString toUnicodeString() const U_OVERRIDE {
     41         // Allocate a UnicodeString of the correct length
     42         UnicodeString output(length(), 0, -1);
     43         for (int32_t i = 0; i < length(); i++) {
     44             output.append(charAt(i));
     45         }
     46         return output;
     47     }
     48 
     49   private:
     50     UnicodeString fStr;
     51 };
     52 
     53 struct MicroProps : public MicroPropsGenerator {
     54 
     55     // NOTE: All of these fields are properly initialized in NumberFormatterImpl.
     56     Rounder rounding;
     57     Grouper grouping;
     58     Padder padding;
     59     IntegerWidth integerWidth;
     60     UNumberSignDisplay sign;
     61     UNumberDecimalSeparatorDisplay decimal;
     62     bool useCurrency;
     63 
     64     // Note: This struct has no direct ownership of the following pointers.
     65     const DecimalFormatSymbols *symbols;
     66     const Modifier *modOuter;
     67     const Modifier *modMiddle;
     68     const Modifier *modInner;
     69 
     70     // The following "helper" fields may optionally be used during the MicroPropsGenerator.
     71     // They live here to retain memory.
     72     struct {
     73         ScientificModifier scientificModifier;
     74         EmptyModifier emptyWeakModifier{false};
     75         EmptyModifier emptyStrongModifier{true};
     76     } helpers;
     77 
     78 
     79     MicroProps() = default;
     80 
     81     MicroProps(const MicroProps &other) = default;
     82 
     83     MicroProps &operator=(const MicroProps &other) = default;
     84 
     85     void processQuantity(DecimalQuantity &, MicroProps &micros, UErrorCode &status) const U_OVERRIDE {
     86         (void)status;
     87         if (this == &micros) {
     88             // Unsafe path: no need to perform a copy.
     89             U_ASSERT(!exhausted);
     90             micros.exhausted = true;
     91             U_ASSERT(exhausted);
     92         } else {
     93             // Safe path: copy self into the output micros.
     94             micros = *this;
     95         }
     96     }
     97 
     98   private:
     99     // Internal fields:
    100     bool exhausted = false;
    101 };
    102 
    103 /**
    104  * This struct provides the result of the number formatting pipeline to FormattedNumber.
    105  *
    106  * The DecimalQuantity is not currently being used by FormattedNumber, but at some point it could be used
    107  * to add a toDecNumber() or similar method.
    108  */
    109 struct NumberFormatterResults : public UMemory {
    110     DecimalQuantity quantity;
    111     NumberStringBuilder string;
    112 };
    113 
    114 inline const UnicodeString getDigitFromSymbols(int8_t digit, const DecimalFormatSymbols &symbols) {
    115     // TODO: Implement DecimalFormatSymbols.getCodePointZero()?
    116     if (digit == 0) {
    117         return symbols.getSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kZeroDigitSymbol);
    118     } else {
    119         return symbols.getSymbol(static_cast<DecimalFormatSymbols::ENumberFormatSymbol>(
    120                                          DecimalFormatSymbols::ENumberFormatSymbol::kOneDigitSymbol + digit - 1));
    121     }
    122 }
    123 
    124 } // namespace impl
    125 } // namespace number
    126 U_NAMESPACE_END
    127 
    128 #endif //__NUMBER_UTILS_H__
    129 
    130 #endif /* #if !UCONFIG_NO_FORMATTING */
    131