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 7 #ifndef __NUMBER_STRINGBUILDER_H__ 8 #define __NUMBER_STRINGBUILDER_H__ 9 10 11 #include <cstdint> 12 #include "unicode/numfmt.h" 13 #include "unicode/ustring.h" 14 #include "cstring.h" 15 #include "uassert.h" 16 #include "number_types.h" 17 #include "fphdlimp.h" 18 19 U_NAMESPACE_BEGIN namespace number { 20 namespace impl { 21 22 class U_I18N_API NumberStringBuilder : public UMemory { 23 private: 24 static const int32_t DEFAULT_CAPACITY = 40; 25 26 template<typename T> 27 union ValueOrHeapArray { 28 T value[DEFAULT_CAPACITY]; 29 struct { 30 T *ptr; 31 int32_t capacity; 32 } heap; 33 }; 34 35 public: 36 NumberStringBuilder(); 37 38 ~NumberStringBuilder(); 39 40 NumberStringBuilder(const NumberStringBuilder &other); 41 42 NumberStringBuilder &operator=(const NumberStringBuilder &other); 43 44 int32_t length() const; 45 46 int32_t codePointCount() const; 47 charAt(int32_t index)48 inline char16_t charAt(int32_t index) const { 49 U_ASSERT(index >= 0); 50 U_ASSERT(index < fLength); 51 return getCharPtr()[fZero + index]; 52 } 53 fieldAt(int32_t index)54 inline Field fieldAt(int32_t index) const { 55 U_ASSERT(index >= 0); 56 U_ASSERT(index < fLength); 57 return getFieldPtr()[fZero + index]; 58 } 59 60 UChar32 getFirstCodePoint() const; 61 62 UChar32 getLastCodePoint() const; 63 64 UChar32 codePointAt(int32_t index) const; 65 66 UChar32 codePointBefore(int32_t index) const; 67 68 NumberStringBuilder &clear(); 69 70 int32_t appendCodePoint(UChar32 codePoint, Field field, UErrorCode &status); 71 72 int32_t insertCodePoint(int32_t index, UChar32 codePoint, Field field, UErrorCode &status); 73 74 int32_t append(const UnicodeString &unistr, Field field, UErrorCode &status); 75 76 int32_t insert(int32_t index, const UnicodeString &unistr, Field field, UErrorCode &status); 77 78 int32_t insert(int32_t index, const UnicodeString &unistr, int32_t start, int32_t end, Field field, 79 UErrorCode &status); 80 81 int32_t splice(int32_t startThis, int32_t endThis, const UnicodeString &unistr, 82 int32_t startOther, int32_t endOther, Field field, UErrorCode& status); 83 84 int32_t append(const NumberStringBuilder &other, UErrorCode &status); 85 86 int32_t insert(int32_t index, const NumberStringBuilder &other, UErrorCode &status); 87 88 /** 89 * Gets a "safe" UnicodeString that can be used even after the NumberStringBuilder is destructed. 90 * */ 91 UnicodeString toUnicodeString() const; 92 93 /** 94 * Gets an "unsafe" UnicodeString that is valid only as long as the NumberStringBuilder is alive and 95 * unchanged. Slightly faster than toUnicodeString(). 96 */ 97 const UnicodeString toTempUnicodeString() const; 98 99 UnicodeString toDebugString() const; 100 101 const char16_t *chars() const; 102 103 bool contentEquals(const NumberStringBuilder &other) const; 104 105 bool nextFieldPosition(FieldPosition& fp, UErrorCode& status) const; 106 107 void getAllFieldPositions(FieldPositionIteratorHandler& fpih, UErrorCode& status) const; 108 109 bool containsField(Field field) const; 110 111 private: 112 bool fUsingHeap = false; 113 ValueOrHeapArray<char16_t> fChars; 114 ValueOrHeapArray<Field> fFields; 115 int32_t fZero = DEFAULT_CAPACITY / 2; 116 int32_t fLength = 0; 117 getCharPtr()118 inline char16_t *getCharPtr() { 119 return fUsingHeap ? fChars.heap.ptr : fChars.value; 120 } 121 getCharPtr()122 inline const char16_t *getCharPtr() const { 123 return fUsingHeap ? fChars.heap.ptr : fChars.value; 124 } 125 getFieldPtr()126 inline Field *getFieldPtr() { 127 return fUsingHeap ? fFields.heap.ptr : fFields.value; 128 } 129 getFieldPtr()130 inline const Field *getFieldPtr() const { 131 return fUsingHeap ? fFields.heap.ptr : fFields.value; 132 } 133 getCapacity()134 inline int32_t getCapacity() const { 135 return fUsingHeap ? fChars.heap.capacity : DEFAULT_CAPACITY; 136 } 137 138 int32_t prepareForInsert(int32_t index, int32_t count, UErrorCode &status); 139 140 int32_t prepareForInsertHelper(int32_t index, int32_t count, UErrorCode &status); 141 142 int32_t remove(int32_t index, int32_t count); 143 }; 144 145 } // namespace impl 146 } // namespace number 147 U_NAMESPACE_END 148 149 150 #endif //__NUMBER_STRINGBUILDER_H__ 151 152 #endif /* #if !UCONFIG_NO_FORMATTING */ 153