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_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 18 U_NAMESPACE_BEGIN namespace number { 19 namespace impl { 20 21 class U_I18N_API NumberStringBuilder : public UMemory { 22 private: 23 static const int32_t DEFAULT_CAPACITY = 40; 24 25 template<typename T> 26 union ValueOrHeapArray { 27 T value[DEFAULT_CAPACITY]; 28 struct { 29 T *ptr; 30 int32_t capacity; 31 } heap; 32 }; 33 34 public: 35 NumberStringBuilder(); 36 37 ~NumberStringBuilder(); 38 39 NumberStringBuilder(const NumberStringBuilder &other); 40 41 NumberStringBuilder &operator=(const NumberStringBuilder &other); 42 43 int32_t length() const; 44 45 int32_t codePointCount() const; 46 charAt(int32_t index)47 inline char16_t charAt(int32_t index) const { 48 U_ASSERT(index >= 0); 49 U_ASSERT(index < fLength); 50 return getCharPtr()[fZero + index]; 51 } 52 fieldAt(int32_t index)53 inline Field fieldAt(int32_t index) const { 54 U_ASSERT(index >= 0); 55 U_ASSERT(index < fLength); 56 return getFieldPtr()[fZero + index]; 57 } 58 59 UChar32 getFirstCodePoint() const; 60 61 UChar32 getLastCodePoint() const; 62 63 UChar32 codePointAt(int32_t index) const; 64 65 UChar32 codePointBefore(int32_t index) const; 66 67 NumberStringBuilder &clear(); 68 69 int32_t appendCodePoint(UChar32 codePoint, Field field, UErrorCode &status); 70 71 int32_t insertCodePoint(int32_t index, UChar32 codePoint, Field field, UErrorCode &status); 72 73 int32_t append(const UnicodeString &unistr, Field field, UErrorCode &status); 74 75 int32_t insert(int32_t index, const UnicodeString &unistr, Field field, UErrorCode &status); 76 77 int32_t insert(int32_t index, const UnicodeString &unistr, int32_t start, int32_t end, Field field, 78 UErrorCode &status); 79 80 int32_t append(const NumberStringBuilder &other, UErrorCode &status); 81 82 int32_t insert(int32_t index, const NumberStringBuilder &other, UErrorCode &status); 83 84 UnicodeString toUnicodeString() const; 85 86 UnicodeString toDebugString() const; 87 88 const char16_t *chars() const; 89 90 bool contentEquals(const NumberStringBuilder &other) const; 91 92 void populateFieldPosition(FieldPosition &fp, int32_t offset, UErrorCode &status) const; 93 94 void populateFieldPositionIterator(FieldPositionIterator &fpi, UErrorCode &status) const; 95 96 private: 97 bool fUsingHeap = false; 98 ValueOrHeapArray<char16_t> fChars; 99 ValueOrHeapArray<Field> fFields; 100 int32_t fZero = DEFAULT_CAPACITY / 2; 101 int32_t fLength = 0; 102 getCharPtr()103 inline char16_t *getCharPtr() { 104 return fUsingHeap ? fChars.heap.ptr : fChars.value; 105 } 106 getCharPtr()107 inline const char16_t *getCharPtr() const { 108 return fUsingHeap ? fChars.heap.ptr : fChars.value; 109 } 110 getFieldPtr()111 inline Field *getFieldPtr() { 112 return fUsingHeap ? fFields.heap.ptr : fFields.value; 113 } 114 getFieldPtr()115 inline const Field *getFieldPtr() const { 116 return fUsingHeap ? fFields.heap.ptr : fFields.value; 117 } 118 getCapacity()119 inline int32_t getCapacity() const { 120 return fUsingHeap ? fChars.heap.capacity : DEFAULT_CAPACITY; 121 } 122 123 int32_t prepareForInsert(int32_t index, int32_t count, UErrorCode &status); 124 125 int32_t prepareForInsertHelper(int32_t index, int32_t count, UErrorCode &status); 126 }; 127 128 } // namespace impl 129 } // namespace number 130 U_NAMESPACE_END 131 132 133 #endif //__NUMBER_STRINGBUILDER_H__ 134 135 #endif /* #if !UCONFIG_NO_FORMATTING */ 136