diff options
Diffstat (limited to 'deps/icu-small/source/i18n')
284 files changed, 5398 insertions, 4253 deletions
diff --git a/deps/icu-small/source/i18n/alphaindex.cpp b/deps/icu-small/source/i18n/alphaindex.cpp index 99f70114cb..532e337383 100644 --- a/deps/icu-small/source/i18n/alphaindex.cpp +++ b/deps/icu-small/source/i18n/alphaindex.cpp @@ -260,8 +260,7 @@ AlphabeticIndex::ImmutableIndex *AlphabeticIndex::buildImmutableIndex(UErrorCode // but that would be worth it only if this method is called multiple times, // or called after using the old-style bucket iterator API. LocalPointer<BucketList> immutableBucketList(createBucketList(errorCode)); - LocalPointer<RuleBasedCollator> coll( - static_cast<RuleBasedCollator *>(collatorPrimaryOnly_->clone())); + LocalPointer<RuleBasedCollator> coll(collatorPrimaryOnly_->clone()); if (immutableBucketList.isNull() || coll.isNull()) { errorCode = U_MEMORY_ALLOCATION_ERROR; return NULL; @@ -907,7 +906,7 @@ void AlphabeticIndex::init(const Locale *locale, UErrorCode &status) { return; } } - collatorPrimaryOnly_ = static_cast<RuleBasedCollator *>(collator_->clone()); + collatorPrimaryOnly_ = collator_->clone(); if (collatorPrimaryOnly_ == NULL) { status = U_MEMORY_ALLOCATION_ERROR; return; @@ -958,7 +957,7 @@ collatorComparator(const void *context, const void *left, const void *right) { } if (leftString == NULL) { return 1; - }; + } if (rightString == NULL) { return -1; } diff --git a/deps/icu-small/source/i18n/anytrans.cpp b/deps/icu-small/source/i18n/anytrans.cpp index 6e382b824b..167b018528 100644 --- a/deps/icu-small/source/i18n/anytrans.cpp +++ b/deps/icu-small/source/i18n/anytrans.cpp @@ -226,7 +226,7 @@ AnyTransliterator::AnyTransliterator(const AnyTransliterator& o) : /** * Transliterator API. */ -Transliterator* AnyTransliterator::clone() const { +AnyTransliterator* AnyTransliterator::clone() const { return new AnyTransliterator(*this); } diff --git a/deps/icu-small/source/i18n/anytrans.h b/deps/icu-small/source/i18n/anytrans.h index 703d42b6d4..627dee3c81 100644 --- a/deps/icu-small/source/i18n/anytrans.h +++ b/deps/icu-small/source/i18n/anytrans.h @@ -66,7 +66,7 @@ public: /** * Transliterator API. */ - virtual Transliterator* clone() const; + virtual AnyTransliterator* clone() const; /** * Implements {@link Transliterator#handleTransliterate}. diff --git a/deps/icu-small/source/i18n/astro.cpp b/deps/icu-small/source/i18n/astro.cpp index 0d521b037d..d28e516472 100644 --- a/deps/icu-small/source/i18n/astro.cpp +++ b/deps/icu-small/source/i18n/astro.cpp @@ -65,10 +65,7 @@ static inline UBool isINVALID(double d) { return(uprv_isNaN(d)); } -static icu::UMutex *ccLock() { - static icu::UMutex m = U_MUTEX_INITIALIZER; - return &m; -} +static icu::UMutex ccLock; U_CDECL_BEGIN static UBool calendar_astro_cleanup(void) { @@ -1552,12 +1549,12 @@ int32_t CalendarCache::get(CalendarCache** cache, int32_t key, UErrorCode &statu if(U_FAILURE(status)) { return 0; } - umtx_lock(ccLock()); + umtx_lock(&ccLock); if(*cache == NULL) { createCache(cache, status); if(U_FAILURE(status)) { - umtx_unlock(ccLock()); + umtx_unlock(&ccLock); return 0; } } @@ -1565,7 +1562,7 @@ int32_t CalendarCache::get(CalendarCache** cache, int32_t key, UErrorCode &statu res = uhash_igeti((*cache)->fTable, key); U_DEBUG_ASTRO_MSG(("%p: GET: [%d] == %d\n", (*cache)->fTable, key, res)); - umtx_unlock(ccLock()); + umtx_unlock(&ccLock); return res; } @@ -1573,12 +1570,12 @@ void CalendarCache::put(CalendarCache** cache, int32_t key, int32_t value, UErro if(U_FAILURE(status)) { return; } - umtx_lock(ccLock()); + umtx_lock(&ccLock); if(*cache == NULL) { createCache(cache, status); if(U_FAILURE(status)) { - umtx_unlock(ccLock()); + umtx_unlock(&ccLock); return; } } @@ -1586,7 +1583,7 @@ void CalendarCache::put(CalendarCache** cache, int32_t key, int32_t value, UErro uhash_iputi((*cache)->fTable, key, value, &status); U_DEBUG_ASTRO_MSG(("%p: PUT: [%d] := %d\n", (*cache)->fTable, key, value)); - umtx_unlock(ccLock()); + umtx_unlock(&ccLock); } CalendarCache::CalendarCache(int32_t size, UErrorCode &status) { diff --git a/deps/icu-small/source/i18n/bocsu.h b/deps/icu-small/source/i18n/bocsu.h index 6b8ed51970..631e29aa76 100644 --- a/deps/icu-small/source/i18n/bocsu.h +++ b/deps/icu-small/source/i18n/bocsu.h @@ -144,14 +144,14 @@ U_NAMESPACE_END * yields negative modulo results and quotients that are one more than * what we need here. */ -#define NEGDIVMOD(n, d, m) { \ +#define NEGDIVMOD(n, d, m) UPRV_BLOCK_MACRO_BEGIN { \ (m)=(n)%(d); \ (n)/=(d); \ if((m)<0) { \ --(n); \ (m)+=(d); \ } \ -} +} UPRV_BLOCK_MACRO_END U_CFUNC UChar32 u_writeIdenticalLevelRun(UChar32 prev, const UChar *s, int32_t length, icu::ByteSink &sink); diff --git a/deps/icu-small/source/i18n/brktrans.cpp b/deps/icu-small/source/i18n/brktrans.cpp index ac9e2afb7e..46b0e345da 100644 --- a/deps/icu-small/source/i18n/brktrans.cpp +++ b/deps/icu-small/source/i18n/brktrans.cpp @@ -64,7 +64,7 @@ BreakTransliterator::BreakTransliterator(const BreakTransliterator& o) : /** * Transliterator API. */ -Transliterator* BreakTransliterator::clone(void) const { +BreakTransliterator* BreakTransliterator::clone() const { return new BreakTransliterator(*this); } diff --git a/deps/icu-small/source/i18n/brktrans.h b/deps/icu-small/source/i18n/brktrans.h index fcc8bdd002..caa1e16ee6 100644 --- a/deps/icu-small/source/i18n/brktrans.h +++ b/deps/icu-small/source/i18n/brktrans.h @@ -54,7 +54,7 @@ public: * Transliterator API. * @return A copy of the object. */ - virtual Transliterator* clone(void) const; + virtual BreakTransliterator* clone() const; virtual const UnicodeString &getInsertion() const; diff --git a/deps/icu-small/source/i18n/buddhcal.cpp b/deps/icu-small/source/i18n/buddhcal.cpp index b6ccbc4749..bddfd1768a 100644 --- a/deps/icu-small/source/i18n/buddhcal.cpp +++ b/deps/icu-small/source/i18n/buddhcal.cpp @@ -53,7 +53,7 @@ BuddhistCalendar& BuddhistCalendar::operator= ( const BuddhistCalendar& right) return *this; } -Calendar* BuddhistCalendar::clone(void) const +BuddhistCalendar* BuddhistCalendar::clone() const { return new BuddhistCalendar(*this); } @@ -133,7 +133,7 @@ void BuddhistCalendar::timeToFields(UDate theTime, UBool quick, UErrorCode& stat */ static UDate gSystemDefaultCenturyStart = DBL_MIN; static int32_t gSystemDefaultCenturyStartYear = -1; -static icu::UInitOnce gBCInitOnce; +static icu::UInitOnce gBCInitOnce = U_INITONCE_INITIALIZER; UBool BuddhistCalendar::haveDefaultCentury() const diff --git a/deps/icu-small/source/i18n/buddhcal.h b/deps/icu-small/source/i18n/buddhcal.h index 89e3f3dec3..c3ffa6a41d 100644 --- a/deps/icu-small/source/i18n/buddhcal.h +++ b/deps/icu-small/source/i18n/buddhcal.h @@ -94,7 +94,7 @@ public: * @return return a polymorphic copy of this calendar. * @internal */ - virtual Calendar* clone(void) const; + virtual BuddhistCalendar* clone() const; public: /** diff --git a/deps/icu-small/source/i18n/calendar.cpp b/deps/icu-small/source/i18n/calendar.cpp index 85a387ef49..9462546561 100644 --- a/deps/icu-small/source/i18n/calendar.cpp +++ b/deps/icu-small/source/i18n/calendar.cpp @@ -268,6 +268,8 @@ static ECalType getCalendarTypeForLocale(const char *locid) { // canonicalize, so grandfathered variant will be transformed to keywords // e.g ja_JP_TRADITIONAL -> ja_JP@calendar=japanese + // NOTE: Since ICU-20187, ja_JP_TRADITIONAL no longer canonicalizes, and + // the Gregorian calendar is returned instead. int32_t canonicalLen = uloc_canonicalize(locid, canonicalName, sizeof(canonicalName) - 1, &status); if (U_FAILURE(status)) { return CALTYPE_GREGORIAN; @@ -748,6 +750,7 @@ fSkippedWallTime(UCAL_WALLTIME_LAST) validLocale[0] = 0; actualLocale[0] = 0; if (U_FAILURE(success)) { + delete zone; return; } if(zone == 0) { @@ -2592,7 +2595,7 @@ Calendar::isWeekend(UDate date, UErrorCode &status) const return FALSE; } // clone the calendar so we don't mess with the real one. - Calendar *work = (Calendar*)this->clone(); + Calendar *work = this->clone(); if (work == NULL) { status = U_MEMORY_ALLOCATION_ERROR; return FALSE; @@ -2752,7 +2755,7 @@ Calendar::getActualMinimum(UCalendarDateFields field, UErrorCode& status) const // clone the calendar so we don't mess with the real one, and set it to // accept anything for the field values - Calendar *work = (Calendar*)this->clone(); + Calendar *work = this->clone(); if (work == NULL) { status = U_MEMORY_ALLOCATION_ERROR; return 0; diff --git a/deps/icu-small/source/i18n/casetrn.cpp b/deps/icu-small/source/i18n/casetrn.cpp index f08d448881..06750b2983 100644 --- a/deps/icu-small/source/i18n/casetrn.cpp +++ b/deps/icu-small/source/i18n/casetrn.cpp @@ -125,7 +125,7 @@ CaseMapTransliterator::CaseMapTransliterator(const CaseMapTransliterator& o) : /** * Transliterator API. */ -/*Transliterator* CaseMapTransliterator::clone(void) const { +/*CaseMapTransliterator* CaseMapTransliterator::clone() const { return new CaseMapTransliterator(*this); }*/ diff --git a/deps/icu-small/source/i18n/casetrn.h b/deps/icu-small/source/i18n/casetrn.h index eee443fc81..47914022f8 100644 --- a/deps/icu-small/source/i18n/casetrn.h +++ b/deps/icu-small/source/i18n/casetrn.h @@ -58,7 +58,7 @@ public: * Transliterator API. * @return a copy of the object. */ - virtual Transliterator* clone(void) const = 0; + virtual CaseMapTransliterator* clone() const = 0; /** * ICU "poor man's RTTI", returns a UClassID for the actual class. diff --git a/deps/icu-small/source/i18n/chnsecal.cpp b/deps/icu-small/source/i18n/chnsecal.cpp index 3c4ad2a846..2ff9f755af 100644 --- a/deps/icu-small/source/i18n/chnsecal.cpp +++ b/deps/icu-small/source/i18n/chnsecal.cpp @@ -51,10 +51,7 @@ static void debug_chnsecal_msg(const char *pat, ...) // --- The cache -- -static icu::UMutex *astroLock() { // Protects access to gChineseCalendarAstro. - static icu::UMutex m = U_MUTEX_INITIALIZER; - return &m; -} +static icu::UMutex astroLock; static icu::CalendarAstronomer *gChineseCalendarAstro = NULL; // Lazy Creation & Access synchronized by class CalendarCache with a mutex. @@ -121,7 +118,7 @@ U_NAMESPACE_BEGIN //------------------------------------------------------------------------- -Calendar* ChineseCalendar::clone() const { +ChineseCalendar* ChineseCalendar::clone() const { return new ChineseCalendar(*this); } @@ -538,14 +535,14 @@ int32_t ChineseCalendar::winterSolstice(int32_t gyear) const { // PST 1298 with a final result of Dec 14 10:31:59 PST 1299. double ms = daysToMillis(Grego::fieldsToDay(gyear, UCAL_DECEMBER, 1)); - umtx_lock(astroLock()); + umtx_lock(&astroLock); if(gChineseCalendarAstro == NULL) { gChineseCalendarAstro = new CalendarAstronomer(); ucln_i18n_registerCleanup(UCLN_I18N_CHINESE_CALENDAR, calendar_chinese_cleanup); } gChineseCalendarAstro->setTime(ms); UDate solarLong = gChineseCalendarAstro->getSunTime(CalendarAstronomer::WINTER_SOLSTICE(), TRUE); - umtx_unlock(astroLock()); + umtx_unlock(&astroLock); // Winter solstice is 270 degrees solar longitude aka Dongzhi cacheValue = (int32_t)millisToDays(solarLong); @@ -568,14 +565,14 @@ int32_t ChineseCalendar::winterSolstice(int32_t gyear) const { */ int32_t ChineseCalendar::newMoonNear(double days, UBool after) const { - umtx_lock(astroLock()); + umtx_lock(&astroLock); if(gChineseCalendarAstro == NULL) { gChineseCalendarAstro = new CalendarAstronomer(); ucln_i18n_registerCleanup(UCLN_I18N_CHINESE_CALENDAR, calendar_chinese_cleanup); } gChineseCalendarAstro->setTime(daysToMillis(days)); UDate newMoon = gChineseCalendarAstro->getMoonTime(CalendarAstronomer::NEW_MOON(), after); - umtx_unlock(astroLock()); + umtx_unlock(&astroLock); return (int32_t) millisToDays(newMoon); } @@ -600,14 +597,14 @@ int32_t ChineseCalendar::synodicMonthsBetween(int32_t day1, int32_t day2) const */ int32_t ChineseCalendar::majorSolarTerm(int32_t days) const { - umtx_lock(astroLock()); + umtx_lock(&astroLock); if(gChineseCalendarAstro == NULL) { gChineseCalendarAstro = new CalendarAstronomer(); ucln_i18n_registerCleanup(UCLN_I18N_CHINESE_CALENDAR, calendar_chinese_cleanup); } gChineseCalendarAstro->setTime(daysToMillis(days)); UDate solarLongitude = gChineseCalendarAstro->getSunLongitude(); - umtx_unlock(astroLock()); + umtx_unlock(&astroLock); // Compute (floor(solarLongitude / (pi/6)) + 2) % 12 int32_t term = ( ((int32_t)(6 * solarLongitude / CalendarAstronomer::PI)) + 2 ) % 12; diff --git a/deps/icu-small/source/i18n/chnsecal.h b/deps/icu-small/source/i18n/chnsecal.h index 1b27d2d1bc..c7c0637381 100644 --- a/deps/icu-small/source/i18n/chnsecal.h +++ b/deps/icu-small/source/i18n/chnsecal.h @@ -144,7 +144,7 @@ class U_I18N_API ChineseCalendar : public Calendar { virtual ~ChineseCalendar(); // clone - virtual Calendar* clone() const; + virtual ChineseCalendar* clone() const; private: diff --git a/deps/icu-small/source/i18n/choicfmt.cpp b/deps/icu-small/source/i18n/choicfmt.cpp index 1b846704bf..16880706d3 100644 --- a/deps/icu-small/source/i18n/choicfmt.cpp +++ b/deps/icu-small/source/i18n/choicfmt.cpp @@ -563,7 +563,7 @@ ChoiceFormat::matchStringUntilLimitPart( // ------------------------------------- -Format* +ChoiceFormat* ChoiceFormat::clone() const { ChoiceFormat *aCopy = new ChoiceFormat(*this); diff --git a/deps/icu-small/source/i18n/coll.cpp b/deps/icu-small/source/i18n/coll.cpp index 8bbe133664..984831e761 100644 --- a/deps/icu-small/source/i18n/coll.cpp +++ b/deps/icu-small/source/i18n/coll.cpp @@ -67,7 +67,7 @@ static int32_t availableLocaleListCount; static icu::ICULocaleService* gService = NULL; static icu::UInitOnce gServiceInitOnce = U_INITONCE_INITIALIZER; #endif -static icu::UInitOnce gAvailableLocaleListInitOnce; +static icu::UInitOnce gAvailableLocaleListInitOnce = U_INITONCE_INITIALIZER; /** * Release all static memory held by collator. diff --git a/deps/icu-small/source/i18n/collationiterator.cpp b/deps/icu-small/source/i18n/collationiterator.cpp index 961c9e9ace..18ccf014f0 100644 --- a/deps/icu-small/source/i18n/collationiterator.cpp +++ b/deps/icu-small/source/i18n/collationiterator.cpp @@ -872,7 +872,7 @@ CollationIterator::previousCE(UVector32 &offsets, UErrorCode &errorCode) { // consistent with forward iteration. while(offsets.size() <= ceBuffer.length) { offsets.addElement(limitOffset, errorCode); - }; + } } return ceBuffer.get(--ceBuffer.length); } else { @@ -932,7 +932,7 @@ CollationIterator::previousCEUnsafe(UChar32 c, UVector32 &offsets, UErrorCode &e offset = getOffset(); while(offsets.size() < ceBuffer.length) { offsets.addElement(offset, errorCode); - }; + } } U_ASSERT(offsets.size() == ceBuffer.length); // End offset corresponding to just after the unsafe-backwards segment. diff --git a/deps/icu-small/source/i18n/compactdecimalformat.cpp b/deps/icu-small/source/i18n/compactdecimalformat.cpp index 4dd2241b23..a4c9dad25c 100644 --- a/deps/icu-small/source/i18n/compactdecimalformat.cpp +++ b/deps/icu-small/source/i18n/compactdecimalformat.cpp @@ -30,9 +30,9 @@ CompactDecimalFormat::CompactDecimalFormat(const Locale& inLocale, UNumberCompac : DecimalFormat(new DecimalFormatSymbols(inLocale, status), status) { if (U_FAILURE(status)) return; // Minimal properties: let the non-shim code path do most of the logic for us. - fields->properties->compactStyle = style; - fields->properties->groupingSize = -2; // do not forward grouping information - fields->properties->minimumGroupingDigits = 2; + fields->properties.compactStyle = style; + fields->properties.groupingSize = -2; // do not forward grouping information + fields->properties.minimumGroupingDigits = 2; touch(status); } @@ -45,7 +45,7 @@ CompactDecimalFormat& CompactDecimalFormat::operator=(const CompactDecimalFormat return *this; } -Format* CompactDecimalFormat::clone() const { +CompactDecimalFormat* CompactDecimalFormat::clone() const { return new CompactDecimalFormat(*this); } diff --git a/deps/icu-small/source/i18n/coptccal.cpp b/deps/icu-small/source/i18n/coptccal.cpp index 39691217d0..229119bf16 100644 --- a/deps/icu-small/source/i18n/coptccal.cpp +++ b/deps/icu-small/source/i18n/coptccal.cpp @@ -40,7 +40,7 @@ CopticCalendar::~CopticCalendar() { } -Calendar* +CopticCalendar* CopticCalendar::clone() const { return new CopticCalendar(*this); diff --git a/deps/icu-small/source/i18n/coptccal.h b/deps/icu-small/source/i18n/coptccal.h index 0b82c36088..dc2d79c89e 100644 --- a/deps/icu-small/source/i18n/coptccal.h +++ b/deps/icu-small/source/i18n/coptccal.h @@ -145,7 +145,7 @@ public: * @return return a polymorphic copy of this calendar. * @internal */ - virtual Calendar* clone(void) const; + virtual CopticCalendar* clone() const; /** * return the calendar type, "coptic" diff --git a/deps/icu-small/source/i18n/cpdtrans.cpp b/deps/icu-small/source/i18n/cpdtrans.cpp index a204de5a53..624ae431d3 100644 --- a/deps/icu-small/source/i18n/cpdtrans.cpp +++ b/deps/icu-small/source/i18n/cpdtrans.cpp @@ -323,7 +323,7 @@ CompoundTransliterator& CompoundTransliterator::operator=( /** * Transliterator API. */ -Transliterator* CompoundTransliterator::clone(void) const { +CompoundTransliterator* CompoundTransliterator::clone() const { return new CompoundTransliterator(*this); } diff --git a/deps/icu-small/source/i18n/cpdtrans.h b/deps/icu-small/source/i18n/cpdtrans.h index 29f3ba83fc..e51b209411 100644 --- a/deps/icu-small/source/i18n/cpdtrans.h +++ b/deps/icu-small/source/i18n/cpdtrans.h @@ -98,7 +98,7 @@ public: /** * Transliterator API. */ - virtual Transliterator* clone(void) const; + virtual CompoundTransliterator* clone() const; /** * Returns the number of transliterators in this chain. diff --git a/deps/icu-small/source/i18n/csdetect.cpp b/deps/icu-small/source/i18n/csdetect.cpp index ad3565155d..566333fec6 100644 --- a/deps/icu-small/source/i18n/csdetect.cpp +++ b/deps/icu-small/source/i18n/csdetect.cpp @@ -47,7 +47,7 @@ struct CSRecognizerInfo : public UMemory { U_NAMESPACE_END static icu::CSRecognizerInfo **fCSRecognizers = NULL; -static icu::UInitOnce gCSRecognizersInitOnce; +static icu::UInitOnce gCSRecognizersInitOnce = U_INITONCE_INITIALIZER; static int32_t fCSRecognizers_size = 0; U_CDECL_BEGIN diff --git a/deps/icu-small/source/i18n/curramt.cpp b/deps/icu-small/source/i18n/curramt.cpp index 019c17df8e..69ab42ace9 100644 --- a/deps/icu-small/source/i18n/curramt.cpp +++ b/deps/icu-small/source/i18n/curramt.cpp @@ -38,7 +38,7 @@ CurrencyAmount& CurrencyAmount::operator=(const CurrencyAmount& other) { return *this; } -UObject* CurrencyAmount::clone() const { +CurrencyAmount* CurrencyAmount::clone() const { return new CurrencyAmount(*this); } diff --git a/deps/icu-small/source/i18n/currfmt.cpp b/deps/icu-small/source/i18n/currfmt.cpp index 8f20f783d2..0ad0492ee7 100644 --- a/deps/icu-small/source/i18n/currfmt.cpp +++ b/deps/icu-small/source/i18n/currfmt.cpp @@ -33,7 +33,7 @@ CurrencyFormat::CurrencyFormat(const CurrencyFormat& other) : CurrencyFormat::~CurrencyFormat() { } -Format* CurrencyFormat::clone() const { +CurrencyFormat* CurrencyFormat::clone() const { return new CurrencyFormat(*this); } diff --git a/deps/icu-small/source/i18n/currfmt.h b/deps/icu-small/source/i18n/currfmt.h index cc9bb3c1ba..69a031957b 100644 --- a/deps/icu-small/source/i18n/currfmt.h +++ b/deps/icu-small/source/i18n/currfmt.h @@ -57,7 +57,7 @@ class CurrencyFormat : public MeasureFormat { /** * Override Format API. */ - virtual Format* clone() const; + virtual CurrencyFormat* clone() const; using MeasureFormat::format; diff --git a/deps/icu-small/source/i18n/currunit.cpp b/deps/icu-small/source/i18n/currunit.cpp index 39c49e468d..03347604a4 100644 --- a/deps/icu-small/source/i18n/currunit.cpp +++ b/deps/icu-small/source/i18n/currunit.cpp @@ -109,7 +109,7 @@ CurrencyUnit& CurrencyUnit::operator=(const CurrencyUnit& other) { return *this; } -UObject* CurrencyUnit::clone() const { +CurrencyUnit* CurrencyUnit::clone() const { return new CurrencyUnit(*this); } diff --git a/deps/icu-small/source/i18n/dangical.cpp b/deps/icu-small/source/i18n/dangical.cpp index bc3951f210..54e2e99fa6 100644 --- a/deps/icu-small/source/i18n/dangical.cpp +++ b/deps/icu-small/source/i18n/dangical.cpp @@ -65,7 +65,7 @@ DangiCalendar::~DangiCalendar() { } -Calendar* +DangiCalendar* DangiCalendar::clone() const { return new DangiCalendar(*this); diff --git a/deps/icu-small/source/i18n/dangical.h b/deps/icu-small/source/i18n/dangical.h index 1a1e06b902..4f2cf384f5 100644 --- a/deps/icu-small/source/i18n/dangical.h +++ b/deps/icu-small/source/i18n/dangical.h @@ -66,7 +66,7 @@ class DangiCalendar : public ChineseCalendar { * Clone. * @internal */ - virtual Calendar* clone() const; + virtual DangiCalendar* clone() const; //---------------------------------------------------------------------- // Internal methods & astronomical calculations diff --git a/deps/icu-small/source/i18n/datefmt.cpp b/deps/icu-small/source/i18n/datefmt.cpp index 039f5bc226..413139db84 100644 --- a/deps/icu-small/source/i18n/datefmt.cpp +++ b/deps/icu-small/source/i18n/datefmt.cpp @@ -154,7 +154,7 @@ DateFormat& DateFormat::operator=(const DateFormat& other) fCalendar = NULL; } if(other.fNumberFormat) { - fNumberFormat = (NumberFormat*)other.fNumberFormat->clone(); + fNumberFormat = other.fNumberFormat->clone(); } else { fNumberFormat = NULL; } @@ -598,7 +598,7 @@ DateFormat::adoptNumberFormat(NumberFormat* newNumberFormat) void DateFormat::setNumberFormat(const NumberFormat& newNumberFormat) { - NumberFormat* newNumFmtClone = (NumberFormat*)newNumberFormat.clone(); + NumberFormat* newNumFmtClone = newNumberFormat.clone(); if (newNumFmtClone != NULL) { adoptNumberFormat(newNumFmtClone); } diff --git a/deps/icu-small/source/i18n/decNumberLocal.h b/deps/icu-small/source/i18n/decNumberLocal.h index f6c291a9ad..e8d1b38653 100644 --- a/deps/icu-small/source/i18n/decNumberLocal.h +++ b/deps/icu-small/source/i18n/decNumberLocal.h @@ -259,7 +259,7 @@ /* 2,000,000,000 (as is needed for negative exponents of */ /* subnormals). The unsigned integer pow is used as a temporary */ /* variable. */ - #define TODIGIT(u, cut, c, pow) { \ + #define TODIGIT(u, cut, c, pow) UPRV_BLOCK_MACRO_BEGIN { \ *(c)='0'; \ pow=DECPOWERS[cut]*2; \ if ((u)>pow) { \ @@ -272,7 +272,7 @@ if ((u)>=pow) {(u)-=pow; *(c)+=2;} \ pow/=2; \ if ((u)>=pow) {(u)-=pow; *(c)+=1;} \ - } + } UPRV_BLOCK_MACRO_END /* ---------------------------------------------------------------- */ /* Definitions for fixed-precision modules (only valid after */ diff --git a/deps/icu-small/source/i18n/decimfmt.cpp b/deps/icu-small/source/i18n/decimfmt.cpp index 2a1e9347fa..6a69c9d7a3 100644 --- a/deps/icu-small/source/i18n/decimfmt.cpp +++ b/deps/icu-small/source/i18n/decimfmt.cpp @@ -95,7 +95,7 @@ DecimalFormat::DecimalFormat(const UnicodeString& pattern, DecimalFormatSymbols* new CurrencyPluralInfo(fields->symbols->getLocale(), status), status); if (U_FAILURE(status)) { return; } - fields->properties->currencyPluralInfo.fPtr.adoptInstead(cpi.orphan()); + fields->properties.currencyPluralInfo.fPtr.adoptInstead(cpi.orphan()); } touch(status); } @@ -111,21 +111,14 @@ DecimalFormat::DecimalFormat(const DecimalFormatSymbols* symbolsToAdopt, UErrorC status = U_MEMORY_ALLOCATION_ERROR; return; } - fields->formatter.adoptInsteadAndCheckErrorCode(new LocalizedNumberFormatter(), status); - fields->properties.adoptInsteadAndCheckErrorCode(new DecimalFormatProperties(), status); - fields->exportedProperties.adoptInsteadAndCheckErrorCode(new DecimalFormatProperties(), status); if (adoptedSymbols.isNull()) { fields->symbols.adoptInsteadAndCheckErrorCode(new DecimalFormatSymbols(status), status); } else { fields->symbols.adoptInsteadAndCheckErrorCode(adoptedSymbols.orphan(), status); } - // In order to simplify error handling logic in the various getters/setters/etc, we do not allow - // any partially populated DecimalFormatFields object. We must have a fully complete fields object - // or else we set it to nullptr. - if (fields->formatter.isNull() || fields->properties.isNull() || fields->exportedProperties.isNull() || fields->symbols.isNull()) { + if (U_FAILURE(status)) { delete fields; fields = nullptr; - status = U_MEMORY_ALLOCATION_ERROR; } } @@ -133,8 +126,8 @@ DecimalFormat::DecimalFormat(const DecimalFormatSymbols* symbolsToAdopt, UErrorC void DecimalFormat::setParseAllInput(UNumberFormatAttributeValue value) { if (fields == nullptr) { return; } - if (value == fields->properties->parseAllInput) { return; } - fields->properties->parseAllInput = value; + if (value == fields->properties.parseAllInput) { return; } + fields->properties.parseAllInput = value; } #endif @@ -379,9 +372,9 @@ void DecimalFormat::setGroupingUsed(UBool enabled) { if (fields == nullptr) { return; } - if (UBOOL_TO_BOOL(enabled) == fields->properties->groupingUsed) { return; } + if (UBOOL_TO_BOOL(enabled) == fields->properties.groupingUsed) { return; } NumberFormat::setGroupingUsed(enabled); // to set field for compatibility - fields->properties->groupingUsed = enabled; + fields->properties.groupingUsed = enabled; touchNoError(); } @@ -389,9 +382,9 @@ void DecimalFormat::setParseIntegerOnly(UBool value) { if (fields == nullptr) { return; } - if (UBOOL_TO_BOOL(value) == fields->properties->parseIntegerOnly) { return; } + if (UBOOL_TO_BOOL(value) == fields->properties.parseIntegerOnly) { return; } NumberFormat::setParseIntegerOnly(value); // to set field for compatibility - fields->properties->parseIntegerOnly = value; + fields->properties.parseIntegerOnly = value; touchNoError(); } @@ -400,9 +393,9 @@ void DecimalFormat::setLenient(UBool enable) { return; } ParseMode mode = enable ? PARSE_MODE_LENIENT : PARSE_MODE_STRICT; - if (!fields->properties->parseMode.isNull() && mode == fields->properties->parseMode.getNoError()) { return; } + if (!fields->properties.parseMode.isNull() && mode == fields->properties.parseMode.getNoError()) { return; } NumberFormat::setLenient(enable); // to set field for compatibility - fields->properties->parseMode = mode; + fields->properties.parseMode = mode; touchNoError(); } @@ -441,19 +434,16 @@ DecimalFormat::DecimalFormat(const DecimalFormat& source) : NumberFormat(source) // Note: it is not safe to copy fields->formatter or fWarehouse directly because fields->formatter might have // dangling pointers to fields inside fWarehouse. The safe thing is to re-construct fields->formatter from // the property bag, despite being somewhat slower. - fields = new DecimalFormatFields(); + fields = new DecimalFormatFields(source.fields->properties); if (fields == nullptr) { return; // no way to report an error. } UErrorCode status = U_ZERO_ERROR; - fields->formatter.adoptInsteadAndCheckErrorCode(new LocalizedNumberFormatter(), status); - fields->properties.adoptInsteadAndCheckErrorCode(new DecimalFormatProperties(*source.fields->properties), status); fields->symbols.adoptInsteadAndCheckErrorCode(new DecimalFormatSymbols(*source.fields->symbols), status); - fields->exportedProperties.adoptInsteadAndCheckErrorCode(new DecimalFormatProperties(), status); // In order to simplify error handling logic in the various getters/setters/etc, we do not allow // any partially populated DecimalFormatFields object. We must have a fully complete fields object // or else we set it to nullptr. - if (fields->formatter.isNull() || fields->properties.isNull() || fields->exportedProperties.isNull() || fields->symbols.isNull()) { + if (U_FAILURE(status)) { delete fields; fields = nullptr; return; @@ -470,8 +460,8 @@ DecimalFormat& DecimalFormat::operator=(const DecimalFormat& rhs) { if (fields == nullptr || rhs.fields == nullptr) { return *this; // unfortunately, no way to report an error. } - *fields->properties = *rhs.fields->properties; - fields->exportedProperties->clear(); + fields->properties = rhs.fields->properties; + fields->exportedProperties.clear(); UErrorCode status = U_ZERO_ERROR; LocalPointer<DecimalFormatSymbols> dfs(new DecimalFormatSymbols(*rhs.fields->symbols), status); if (U_FAILURE(status)) { @@ -495,7 +485,7 @@ DecimalFormat::~DecimalFormat() { delete fields; } -Format* DecimalFormat::clone() const { +DecimalFormat* DecimalFormat::clone() const { // can only clone valid objects. if (fields == nullptr) { return nullptr; @@ -517,7 +507,7 @@ UBool DecimalFormat::operator==(const Format& other) const { if (fields == nullptr || otherDF->fields == nullptr) { return false; } - return *fields->properties == *otherDF->fields->properties && *fields->symbols == *otherDF->fields->symbols; + return fields->properties == otherDF->fields->properties && *fields->symbols == *otherDF->fields->symbols; } UnicodeString& DecimalFormat::format(double number, UnicodeString& appendTo, FieldPosition& pos) const { @@ -529,7 +519,7 @@ UnicodeString& DecimalFormat::format(double number, UnicodeString& appendTo, Fie return appendTo; } UErrorCode localStatus = U_ZERO_ERROR; - FormattedNumber output = fields->formatter->formatDouble(number, localStatus); + FormattedNumber output = fields->formatter.formatDouble(number, localStatus); fieldPositionHelper(output, pos, appendTo.length(), localStatus); auto appendable = UnicodeStringAppendable(appendTo); output.appendTo(appendable, localStatus); @@ -550,7 +540,7 @@ UnicodeString& DecimalFormat::format(double number, UnicodeString& appendTo, Fie if (pos.getField() == FieldPosition::DONT_CARE && fastFormatDouble(number, appendTo)) { return appendTo; } - FormattedNumber output = fields->formatter->formatDouble(number, status); + FormattedNumber output = fields->formatter.formatDouble(number, status); fieldPositionHelper(output, pos, appendTo.length(), status); auto appendable = UnicodeStringAppendable(appendTo); output.appendTo(appendable, status); @@ -572,7 +562,7 @@ DecimalFormat::format(double number, UnicodeString& appendTo, FieldPositionItera if (posIter == nullptr && fastFormatDouble(number, appendTo)) { return appendTo; } - FormattedNumber output = fields->formatter->formatDouble(number, status); + FormattedNumber output = fields->formatter.formatDouble(number, status); fieldPositionIteratorHelper(output, posIter, appendTo.length(), status); auto appendable = UnicodeStringAppendable(appendTo); output.appendTo(appendable, status); @@ -603,7 +593,7 @@ UnicodeString& DecimalFormat::format(int64_t number, UnicodeString& appendTo, Fi return appendTo; } UErrorCode localStatus = U_ZERO_ERROR; - FormattedNumber output = fields->formatter->formatInt(number, localStatus); + FormattedNumber output = fields->formatter.formatInt(number, localStatus); fieldPositionHelper(output, pos, appendTo.length(), localStatus); auto appendable = UnicodeStringAppendable(appendTo); output.appendTo(appendable, localStatus); @@ -624,7 +614,7 @@ UnicodeString& DecimalFormat::format(int64_t number, UnicodeString& appendTo, Fi if (pos.getField() == FieldPosition::DONT_CARE && fastFormatInt64(number, appendTo)) { return appendTo; } - FormattedNumber output = fields->formatter->formatInt(number, status); + FormattedNumber output = fields->formatter.formatInt(number, status); fieldPositionHelper(output, pos, appendTo.length(), status); auto appendable = UnicodeStringAppendable(appendTo); output.appendTo(appendable, status); @@ -646,7 +636,7 @@ DecimalFormat::format(int64_t number, UnicodeString& appendTo, FieldPositionIter if (posIter == nullptr && fastFormatInt64(number, appendTo)) { return appendTo; } - FormattedNumber output = fields->formatter->formatInt(number, status); + FormattedNumber output = fields->formatter.formatInt(number, status); fieldPositionIteratorHelper(output, posIter, appendTo.length(), status); auto appendable = UnicodeStringAppendable(appendTo); output.appendTo(appendable, status); @@ -665,7 +655,7 @@ DecimalFormat::format(StringPiece number, UnicodeString& appendTo, FieldPosition appendTo.setToBogus(); return appendTo; } - FormattedNumber output = fields->formatter->formatDecimal(number, status); + FormattedNumber output = fields->formatter.formatDecimal(number, status); fieldPositionIteratorHelper(output, posIter, appendTo.length(), status); auto appendable = UnicodeStringAppendable(appendTo); output.appendTo(appendable, status); @@ -683,7 +673,7 @@ UnicodeString& DecimalFormat::format(const DecimalQuantity& number, UnicodeStrin appendTo.setToBogus(); return appendTo; } - FormattedNumber output = fields->formatter->formatDecimalQuantity(number, status); + FormattedNumber output = fields->formatter.formatDecimalQuantity(number, status); fieldPositionIteratorHelper(output, posIter, appendTo.length(), status); auto appendable = UnicodeStringAppendable(appendTo); output.appendTo(appendable, status); @@ -702,7 +692,7 @@ DecimalFormat::format(const DecimalQuantity& number, UnicodeString& appendTo, Fi appendTo.setToBogus(); return appendTo; } - FormattedNumber output = fields->formatter->formatDecimalQuantity(number, status); + FormattedNumber output = fields->formatter.formatDecimalQuantity(number, status); fieldPositionHelper(output, pos, appendTo.length(), status); auto appendable = UnicodeStringAppendable(appendTo); output.appendTo(appendable, status); @@ -823,7 +813,7 @@ const CurrencyPluralInfo* DecimalFormat::getCurrencyPluralInfo(void) const { if (fields == nullptr) { return nullptr; } - return fields->properties->currencyPluralInfo.fPtr.getAlias(); + return fields->properties.currencyPluralInfo.fPtr.getAlias(); } void DecimalFormat::adoptCurrencyPluralInfo(CurrencyPluralInfo* toAdopt) { @@ -833,7 +823,7 @@ void DecimalFormat::adoptCurrencyPluralInfo(CurrencyPluralInfo* toAdopt) { if (fields == nullptr) { return; } - fields->properties->currencyPluralInfo.fPtr.adoptInstead(cpi.orphan()); + fields->properties.currencyPluralInfo.fPtr.adoptInstead(cpi.orphan()); touchNoError(); } @@ -841,11 +831,11 @@ void DecimalFormat::setCurrencyPluralInfo(const CurrencyPluralInfo& info) { if (fields == nullptr) { return; } - if (fields->properties->currencyPluralInfo.fPtr.isNull()) { + if (fields->properties.currencyPluralInfo.fPtr.isNull()) { // Note: clone() can fail with OOM error, but we have no way to report it. :( - fields->properties->currencyPluralInfo.fPtr.adoptInstead(info.clone()); + fields->properties.currencyPluralInfo.fPtr.adoptInstead(info.clone()); } else { - *fields->properties->currencyPluralInfo.fPtr = info; // copy-assignment operator + *fields->properties.currencyPluralInfo.fPtr = info; // copy-assignment operator } touchNoError(); } @@ -856,7 +846,7 @@ UnicodeString& DecimalFormat::getPositivePrefix(UnicodeString& result) const { return result; } UErrorCode status = U_ZERO_ERROR; - fields->formatter->getAffixImpl(true, false, result, status); + fields->formatter.getAffixImpl(true, false, result, status); if (U_FAILURE(status)) { result.setToBogus(); } return result; } @@ -865,8 +855,8 @@ void DecimalFormat::setPositivePrefix(const UnicodeString& newValue) { if (fields == nullptr) { return; } - if (newValue == fields->properties->positivePrefix) { return; } - fields->properties->positivePrefix = newValue; + if (newValue == fields->properties.positivePrefix) { return; } + fields->properties.positivePrefix = newValue; touchNoError(); } @@ -876,7 +866,7 @@ UnicodeString& DecimalFormat::getNegativePrefix(UnicodeString& result) const { return result; } UErrorCode status = U_ZERO_ERROR; - fields->formatter->getAffixImpl(true, true, result, status); + fields->formatter.getAffixImpl(true, true, result, status); if (U_FAILURE(status)) { result.setToBogus(); } return result; } @@ -885,8 +875,8 @@ void DecimalFormat::setNegativePrefix(const UnicodeString& newValue) { if (fields == nullptr) { return; } - if (newValue == fields->properties->negativePrefix) { return; } - fields->properties->negativePrefix = newValue; + if (newValue == fields->properties.negativePrefix) { return; } + fields->properties.negativePrefix = newValue; touchNoError(); } @@ -896,7 +886,7 @@ UnicodeString& DecimalFormat::getPositiveSuffix(UnicodeString& result) const { return result; } UErrorCode status = U_ZERO_ERROR; - fields->formatter->getAffixImpl(false, false, result, status); + fields->formatter.getAffixImpl(false, false, result, status); if (U_FAILURE(status)) { result.setToBogus(); } return result; } @@ -905,8 +895,8 @@ void DecimalFormat::setPositiveSuffix(const UnicodeString& newValue) { if (fields == nullptr) { return; } - if (newValue == fields->properties->positiveSuffix) { return; } - fields->properties->positiveSuffix = newValue; + if (newValue == fields->properties.positiveSuffix) { return; } + fields->properties.positiveSuffix = newValue; touchNoError(); } @@ -916,7 +906,7 @@ UnicodeString& DecimalFormat::getNegativeSuffix(UnicodeString& result) const { return result; } UErrorCode status = U_ZERO_ERROR; - fields->formatter->getAffixImpl(false, true, result, status); + fields->formatter.getAffixImpl(false, true, result, status); if (U_FAILURE(status)) { result.setToBogus(); } return result; } @@ -925,8 +915,8 @@ void DecimalFormat::setNegativeSuffix(const UnicodeString& newValue) { if (fields == nullptr) { return; } - if (newValue == fields->properties->negativeSuffix) { return; } - fields->properties->negativeSuffix = newValue; + if (newValue == fields->properties.negativeSuffix) { return; } + fields->properties.negativeSuffix = newValue; touchNoError(); } @@ -935,13 +925,13 @@ UBool DecimalFormat::isSignAlwaysShown() const { if (fields == nullptr) { return DecimalFormatProperties::getDefault().signAlwaysShown; } - return fields->properties->signAlwaysShown; + return fields->properties.signAlwaysShown; } void DecimalFormat::setSignAlwaysShown(UBool value) { if (fields == nullptr) { return; } - if (UBOOL_TO_BOOL(value) == fields->properties->signAlwaysShown) { return; } - fields->properties->signAlwaysShown = value; + if (UBOOL_TO_BOOL(value) == fields->properties.signAlwaysShown) { return; } + fields->properties.signAlwaysShown = value; touchNoError(); } @@ -952,7 +942,7 @@ int32_t DecimalFormat::getMultiplier(void) const { // Fallback to using the default instance of DecimalFormatProperties. dfp = &(DecimalFormatProperties::getDefault()); } else { - dfp = fields->properties.getAlias(); + dfp = &fields->properties; } if (dfp->multiplier != 1) { return dfp->multiplier; @@ -984,11 +974,11 @@ void DecimalFormat::setMultiplier(int32_t multiplier) { value = temp; } if (delta != -1) { - fields->properties->magnitudeMultiplier = delta; - fields->properties->multiplier = 1; + fields->properties.magnitudeMultiplier = delta; + fields->properties.multiplier = 1; } else { - fields->properties->magnitudeMultiplier = 0; - fields->properties->multiplier = multiplier; + fields->properties.magnitudeMultiplier = 0; + fields->properties.multiplier = multiplier; } touchNoError(); } @@ -999,13 +989,13 @@ int32_t DecimalFormat::getMultiplierScale() const { // Fallback to using the default instance of DecimalFormatProperties. return DecimalFormatProperties::getDefault().multiplierScale; } - return fields->properties->multiplierScale; + return fields->properties.multiplierScale; } void DecimalFormat::setMultiplierScale(int32_t newValue) { if (fields == nullptr) { return; } - if (newValue == fields->properties->multiplierScale) { return; } - fields->properties->multiplierScale = newValue; + if (newValue == fields->properties.multiplierScale) { return; } + fields->properties.multiplierScale = newValue; touchNoError(); } @@ -1015,13 +1005,13 @@ double DecimalFormat::getRoundingIncrement(void) const { // Fallback to using the default instance of DecimalFormatProperties. return DecimalFormatProperties::getDefault().roundingIncrement; } - return fields->exportedProperties->roundingIncrement; + return fields->exportedProperties.roundingIncrement; } void DecimalFormat::setRoundingIncrement(double newValue) { if (fields == nullptr) { return; } - if (newValue == fields->properties->roundingIncrement) { return; } - fields->properties->roundingIncrement = newValue; + if (newValue == fields->properties.roundingIncrement) { return; } + fields->properties.roundingIncrement = newValue; touchNoError(); } @@ -1032,17 +1022,17 @@ ERoundingMode DecimalFormat::getRoundingMode(void) const { return static_cast<ERoundingMode>(DecimalFormatProperties::getDefault().roundingMode.getNoError()); } // UNumberFormatRoundingMode and ERoundingMode have the same values. - return static_cast<ERoundingMode>(fields->exportedProperties->roundingMode.getNoError()); + return static_cast<ERoundingMode>(fields->exportedProperties.roundingMode.getNoError()); } void DecimalFormat::setRoundingMode(ERoundingMode roundingMode) { if (fields == nullptr) { return; } auto uRoundingMode = static_cast<UNumberFormatRoundingMode>(roundingMode); - if (!fields->properties->roundingMode.isNull() && uRoundingMode == fields->properties->roundingMode.getNoError()) { + if (!fields->properties.roundingMode.isNull() && uRoundingMode == fields->properties.roundingMode.getNoError()) { return; } NumberFormat::setMaximumIntegerDigits(roundingMode); // to set field for compatibility - fields->properties->roundingMode = uRoundingMode; + fields->properties.roundingMode = uRoundingMode; touchNoError(); } @@ -1052,52 +1042,52 @@ int32_t DecimalFormat::getFormatWidth(void) const { // Fallback to using the default instance of DecimalFormatProperties. return DecimalFormatProperties::getDefault().formatWidth; } - return fields->properties->formatWidth; + return fields->properties.formatWidth; } void DecimalFormat::setFormatWidth(int32_t width) { if (fields == nullptr) { return; } - if (width == fields->properties->formatWidth) { return; } - fields->properties->formatWidth = width; + if (width == fields->properties.formatWidth) { return; } + fields->properties.formatWidth = width; touchNoError(); } UnicodeString DecimalFormat::getPadCharacterString() const { - if (fields == nullptr || fields->properties->padString.isBogus()) { + if (fields == nullptr || fields->properties.padString.isBogus()) { // Readonly-alias the static string kFallbackPaddingString return {TRUE, kFallbackPaddingString, -1}; } else { - return fields->properties->padString; + return fields->properties.padString; } } void DecimalFormat::setPadCharacter(const UnicodeString& padChar) { if (fields == nullptr) { return; } - if (padChar == fields->properties->padString) { return; } + if (padChar == fields->properties.padString) { return; } if (padChar.length() > 0) { - fields->properties->padString = UnicodeString(padChar.char32At(0)); + fields->properties.padString = UnicodeString(padChar.char32At(0)); } else { - fields->properties->padString.setToBogus(); + fields->properties.padString.setToBogus(); } touchNoError(); } EPadPosition DecimalFormat::getPadPosition(void) const { - if (fields == nullptr || fields->properties->padPosition.isNull()) { + if (fields == nullptr || fields->properties.padPosition.isNull()) { return EPadPosition::kPadBeforePrefix; } else { // UNumberFormatPadPosition and EPadPosition have the same values. - return static_cast<EPadPosition>(fields->properties->padPosition.getNoError()); + return static_cast<EPadPosition>(fields->properties.padPosition.getNoError()); } } void DecimalFormat::setPadPosition(EPadPosition padPos) { if (fields == nullptr) { return; } auto uPadPos = static_cast<UNumberFormatPadPosition>(padPos); - if (!fields->properties->padPosition.isNull() && uPadPos == fields->properties->padPosition.getNoError()) { + if (!fields->properties.padPosition.isNull() && uPadPos == fields->properties.padPosition.getNoError()) { return; } - fields->properties->padPosition = uPadPos; + fields->properties.padPosition = uPadPos; touchNoError(); } @@ -1107,17 +1097,17 @@ UBool DecimalFormat::isScientificNotation(void) const { // Fallback to using the default instance of DecimalFormatProperties. return (DecimalFormatProperties::getDefault().minimumExponentDigits != -1); } - return (fields->properties->minimumExponentDigits != -1); + return (fields->properties.minimumExponentDigits != -1); } void DecimalFormat::setScientificNotation(UBool useScientific) { if (fields == nullptr) { return; } int32_t minExp = useScientific ? 1 : -1; - if (fields->properties->minimumExponentDigits == minExp) { return; } + if (fields->properties.minimumExponentDigits == minExp) { return; } if (useScientific) { - fields->properties->minimumExponentDigits = 1; + fields->properties.minimumExponentDigits = 1; } else { - fields->properties->minimumExponentDigits = -1; + fields->properties.minimumExponentDigits = -1; } touchNoError(); } @@ -1128,13 +1118,13 @@ int8_t DecimalFormat::getMinimumExponentDigits(void) const { // Fallback to using the default instance of DecimalFormatProperties. return static_cast<int8_t>(DecimalFormatProperties::getDefault().minimumExponentDigits); } - return static_cast<int8_t>(fields->properties->minimumExponentDigits); + return static_cast<int8_t>(fields->properties.minimumExponentDigits); } void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig) { if (fields == nullptr) { return; } - if (minExpDig == fields->properties->minimumExponentDigits) { return; } - fields->properties->minimumExponentDigits = minExpDig; + if (minExpDig == fields->properties.minimumExponentDigits) { return; } + fields->properties.minimumExponentDigits = minExpDig; touchNoError(); } @@ -1144,13 +1134,13 @@ UBool DecimalFormat::isExponentSignAlwaysShown(void) const { // Fallback to using the default instance of DecimalFormatProperties. return DecimalFormatProperties::getDefault().exponentSignAlwaysShown; } - return fields->properties->exponentSignAlwaysShown; + return fields->properties.exponentSignAlwaysShown; } void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways) { if (fields == nullptr) { return; } - if (UBOOL_TO_BOOL(expSignAlways) == fields->properties->exponentSignAlwaysShown) { return; } - fields->properties->exponentSignAlwaysShown = expSignAlways; + if (UBOOL_TO_BOOL(expSignAlways) == fields->properties.exponentSignAlwaysShown) { return; } + fields->properties.exponentSignAlwaysShown = expSignAlways; touchNoError(); } @@ -1161,7 +1151,7 @@ int32_t DecimalFormat::getGroupingSize(void) const { // Fallback to using the default instance of DecimalFormatProperties. groupingSize = DecimalFormatProperties::getDefault().groupingSize; } else { - groupingSize = fields->properties->groupingSize; + groupingSize = fields->properties.groupingSize; } if (groupingSize < 0) { return 0; @@ -1171,8 +1161,8 @@ int32_t DecimalFormat::getGroupingSize(void) const { void DecimalFormat::setGroupingSize(int32_t newValue) { if (fields == nullptr) { return; } - if (newValue == fields->properties->groupingSize) { return; } - fields->properties->groupingSize = newValue; + if (newValue == fields->properties.groupingSize) { return; } + fields->properties.groupingSize = newValue; touchNoError(); } @@ -1183,7 +1173,7 @@ int32_t DecimalFormat::getSecondaryGroupingSize(void) const { // Fallback to using the default instance of DecimalFormatProperties. grouping2 = DecimalFormatProperties::getDefault().secondaryGroupingSize; } else { - grouping2 = fields->properties->secondaryGroupingSize; + grouping2 = fields->properties.secondaryGroupingSize; } if (grouping2 < 0) { return 0; @@ -1193,8 +1183,8 @@ int32_t DecimalFormat::getSecondaryGroupingSize(void) const { void DecimalFormat::setSecondaryGroupingSize(int32_t newValue) { if (fields == nullptr) { return; } - if (newValue == fields->properties->secondaryGroupingSize) { return; } - fields->properties->secondaryGroupingSize = newValue; + if (newValue == fields->properties.secondaryGroupingSize) { return; } + fields->properties.secondaryGroupingSize = newValue; touchNoError(); } @@ -1204,13 +1194,13 @@ int32_t DecimalFormat::getMinimumGroupingDigits() const { // Fallback to using the default instance of DecimalFormatProperties. return DecimalFormatProperties::getDefault().minimumGroupingDigits; } - return fields->properties->minimumGroupingDigits; + return fields->properties.minimumGroupingDigits; } void DecimalFormat::setMinimumGroupingDigits(int32_t newValue) { if (fields == nullptr) { return; } - if (newValue == fields->properties->minimumGroupingDigits) { return; } - fields->properties->minimumGroupingDigits = newValue; + if (newValue == fields->properties.minimumGroupingDigits) { return; } + fields->properties.minimumGroupingDigits = newValue; touchNoError(); } @@ -1220,13 +1210,13 @@ UBool DecimalFormat::isDecimalSeparatorAlwaysShown(void) const { // Fallback to using the default instance of DecimalFormatProperties. return DecimalFormatProperties::getDefault().decimalSeparatorAlwaysShown; } - return fields->properties->decimalSeparatorAlwaysShown; + return fields->properties.decimalSeparatorAlwaysShown; } void DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue) { if (fields == nullptr) { return; } - if (UBOOL_TO_BOOL(newValue) == fields->properties->decimalSeparatorAlwaysShown) { return; } - fields->properties->decimalSeparatorAlwaysShown = newValue; + if (UBOOL_TO_BOOL(newValue) == fields->properties.decimalSeparatorAlwaysShown) { return; } + fields->properties.decimalSeparatorAlwaysShown = newValue; touchNoError(); } @@ -1236,13 +1226,13 @@ UBool DecimalFormat::isDecimalPatternMatchRequired(void) const { // Fallback to using the default instance of DecimalFormatProperties. return DecimalFormatProperties::getDefault().decimalPatternMatchRequired; } - return fields->properties->decimalPatternMatchRequired; + return fields->properties.decimalPatternMatchRequired; } void DecimalFormat::setDecimalPatternMatchRequired(UBool newValue) { if (fields == nullptr) { return; } - if (UBOOL_TO_BOOL(newValue) == fields->properties->decimalPatternMatchRequired) { return; } - fields->properties->decimalPatternMatchRequired = newValue; + if (UBOOL_TO_BOOL(newValue) == fields->properties.decimalPatternMatchRequired) { return; } + fields->properties.decimalPatternMatchRequired = newValue; touchNoError(); } @@ -1252,13 +1242,13 @@ UBool DecimalFormat::isParseNoExponent() const { // Fallback to using the default instance of DecimalFormatProperties. return DecimalFormatProperties::getDefault().parseNoExponent; } - return fields->properties->parseNoExponent; + return fields->properties.parseNoExponent; } void DecimalFormat::setParseNoExponent(UBool value) { if (fields == nullptr) { return; } - if (UBOOL_TO_BOOL(value) == fields->properties->parseNoExponent) { return; } - fields->properties->parseNoExponent = value; + if (UBOOL_TO_BOOL(value) == fields->properties.parseNoExponent) { return; } + fields->properties.parseNoExponent = value; touchNoError(); } @@ -1268,13 +1258,13 @@ UBool DecimalFormat::isParseCaseSensitive() const { // Fallback to using the default instance of DecimalFormatProperties. return DecimalFormatProperties::getDefault().parseCaseSensitive; } - return fields->properties->parseCaseSensitive; + return fields->properties.parseCaseSensitive; } void DecimalFormat::setParseCaseSensitive(UBool value) { if (fields == nullptr) { return; } - if (UBOOL_TO_BOOL(value) == fields->properties->parseCaseSensitive) { return; } - fields->properties->parseCaseSensitive = value; + if (UBOOL_TO_BOOL(value) == fields->properties.parseCaseSensitive) { return; } + fields->properties.parseCaseSensitive = value; touchNoError(); } @@ -1284,13 +1274,13 @@ UBool DecimalFormat::isFormatFailIfMoreThanMaxDigits() const { // Fallback to using the default instance of DecimalFormatProperties. return DecimalFormatProperties::getDefault().formatFailIfMoreThanMaxDigits; } - return fields->properties->formatFailIfMoreThanMaxDigits; + return fields->properties.formatFailIfMoreThanMaxDigits; } void DecimalFormat::setFormatFailIfMoreThanMaxDigits(UBool value) { if (fields == nullptr) { return; } - if (UBOOL_TO_BOOL(value) == fields->properties->formatFailIfMoreThanMaxDigits) { return; } - fields->properties->formatFailIfMoreThanMaxDigits = value; + if (UBOOL_TO_BOOL(value) == fields->properties.formatFailIfMoreThanMaxDigits) { return; } + fields->properties.formatFailIfMoreThanMaxDigits = value; touchNoError(); } @@ -1305,7 +1295,7 @@ UnicodeString& DecimalFormat::toPattern(UnicodeString& result) const { // so that CurrencyUsage is reflected properly. // TODO: Consider putting this logic in number_patternstring.cpp instead. ErrorCode localStatus; - DecimalFormatProperties tprops(*fields->properties); + DecimalFormatProperties tprops(fields->properties); bool useCurrency = ( !tprops.currency.isNull() || !tprops.currencyPluralInfo.fPtr.isNull() || @@ -1315,9 +1305,9 @@ UnicodeString& DecimalFormat::toPattern(UnicodeString& result) const { AffixUtils::hasCurrencySymbols(tprops.negativePrefixPattern, localStatus) || AffixUtils::hasCurrencySymbols(tprops.negativeSuffixPattern, localStatus)); if (useCurrency) { - tprops.minimumFractionDigits = fields->exportedProperties->minimumFractionDigits; - tprops.maximumFractionDigits = fields->exportedProperties->maximumFractionDigits; - tprops.roundingIncrement = fields->exportedProperties->roundingIncrement; + tprops.minimumFractionDigits = fields->exportedProperties.minimumFractionDigits; + tprops.maximumFractionDigits = fields->exportedProperties.maximumFractionDigits; + tprops.roundingIncrement = fields->exportedProperties.roundingIncrement; } result = PatternStringUtils::propertiesToPatternString(tprops, localStatus); return result; @@ -1373,49 +1363,53 @@ void DecimalFormat::applyLocalizedPattern(const UnicodeString& localizedPattern, void DecimalFormat::setMaximumIntegerDigits(int32_t newValue) { if (fields == nullptr) { return; } - if (newValue == fields->properties->maximumIntegerDigits) { return; } + if (newValue == fields->properties.maximumIntegerDigits) { return; } // For backwards compatibility, conflicting min/max need to keep the most recent setting. - int32_t min = fields->properties->minimumIntegerDigits; + int32_t min = fields->properties.minimumIntegerDigits; if (min >= 0 && min > newValue) { - fields->properties->minimumIntegerDigits = newValue; + fields->properties.minimumIntegerDigits = newValue; } - fields->properties->maximumIntegerDigits = newValue; + fields->properties.maximumIntegerDigits = newValue; touchNoError(); } void DecimalFormat::setMinimumIntegerDigits(int32_t newValue) { if (fields == nullptr) { return; } - if (newValue == fields->properties->minimumIntegerDigits) { return; } + if (newValue == fields->properties.minimumIntegerDigits) { return; } // For backwards compatibility, conflicting min/max need to keep the most recent setting. - int32_t max = fields->properties->maximumIntegerDigits; + int32_t max = fields->properties.maximumIntegerDigits; if (max >= 0 && max < newValue) { - fields->properties->maximumIntegerDigits = newValue; + fields->properties.maximumIntegerDigits = newValue; } - fields->properties->minimumIntegerDigits = newValue; + fields->properties.minimumIntegerDigits = newValue; touchNoError(); } void DecimalFormat::setMaximumFractionDigits(int32_t newValue) { if (fields == nullptr) { return; } - if (newValue == fields->properties->maximumFractionDigits) { return; } + if (newValue == fields->properties.maximumFractionDigits) { return; } + // cap for backward compatibility, formerly 340, now 999 + if (newValue > kMaxIntFracSig) { + newValue = kMaxIntFracSig; + } // For backwards compatibility, conflicting min/max need to keep the most recent setting. - int32_t min = fields->properties->minimumFractionDigits; + int32_t min = fields->properties.minimumFractionDigits; if (min >= 0 && min > newValue) { - fields->properties->minimumFractionDigits = newValue; + fields->properties.minimumFractionDigits = newValue; } - fields->properties->maximumFractionDigits = newValue; + fields->properties.maximumFractionDigits = newValue; touchNoError(); } void DecimalFormat::setMinimumFractionDigits(int32_t newValue) { if (fields == nullptr) { return; } - if (newValue == fields->properties->minimumFractionDigits) { return; } + if (newValue == fields->properties.minimumFractionDigits) { return; } // For backwards compatibility, conflicting min/max need to keep the most recent setting. - int32_t max = fields->properties->maximumFractionDigits; + int32_t max = fields->properties.maximumFractionDigits; if (max >= 0 && max < newValue) { - fields->properties->maximumFractionDigits = newValue; + fields->properties.maximumFractionDigits = newValue; } - fields->properties->minimumFractionDigits = newValue; + fields->properties.minimumFractionDigits = newValue; touchNoError(); } @@ -1425,7 +1419,7 @@ int32_t DecimalFormat::getMinimumSignificantDigits() const { // Fallback to using the default instance of DecimalFormatProperties. return DecimalFormatProperties::getDefault().minimumSignificantDigits; } - return fields->exportedProperties->minimumSignificantDigits; + return fields->exportedProperties.minimumSignificantDigits; } int32_t DecimalFormat::getMaximumSignificantDigits() const { @@ -1434,28 +1428,28 @@ int32_t DecimalFormat::getMaximumSignificantDigits() const { // Fallback to using the default instance of DecimalFormatProperties. return DecimalFormatProperties::getDefault().maximumSignificantDigits; } - return fields->exportedProperties->maximumSignificantDigits; + return fields->exportedProperties.maximumSignificantDigits; } void DecimalFormat::setMinimumSignificantDigits(int32_t value) { if (fields == nullptr) { return; } - if (value == fields->properties->minimumSignificantDigits) { return; } - int32_t max = fields->properties->maximumSignificantDigits; + if (value == fields->properties.minimumSignificantDigits) { return; } + int32_t max = fields->properties.maximumSignificantDigits; if (max >= 0 && max < value) { - fields->properties->maximumSignificantDigits = value; + fields->properties.maximumSignificantDigits = value; } - fields->properties->minimumSignificantDigits = value; + fields->properties.minimumSignificantDigits = value; touchNoError(); } void DecimalFormat::setMaximumSignificantDigits(int32_t value) { if (fields == nullptr) { return; } - if (value == fields->properties->maximumSignificantDigits) { return; } - int32_t min = fields->properties->minimumSignificantDigits; + if (value == fields->properties.maximumSignificantDigits) { return; } + int32_t min = fields->properties.minimumSignificantDigits; if (min >= 0 && min > value) { - fields->properties->minimumSignificantDigits = value; + fields->properties.minimumSignificantDigits = value; } - fields->properties->maximumSignificantDigits = value; + fields->properties.maximumSignificantDigits = value; touchNoError(); } @@ -1466,7 +1460,7 @@ UBool DecimalFormat::areSignificantDigitsUsed() const { // Fallback to using the default instance of DecimalFormatProperties. dfp = &(DecimalFormatProperties::getDefault()); } else { - dfp = fields->properties.getAlias(); + dfp = &fields->properties; } return dfp->minimumSignificantDigits != -1 || dfp->maximumSignificantDigits != -1; } @@ -1476,20 +1470,20 @@ void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits) { // These are the default values from the old implementation. if (useSignificantDigits) { - if (fields->properties->minimumSignificantDigits != -1 || - fields->properties->maximumSignificantDigits != -1) { + if (fields->properties.minimumSignificantDigits != -1 || + fields->properties.maximumSignificantDigits != -1) { return; } } else { - if (fields->properties->minimumSignificantDigits == -1 && - fields->properties->maximumSignificantDigits == -1) { + if (fields->properties.minimumSignificantDigits == -1 && + fields->properties.maximumSignificantDigits == -1) { return; } } int32_t minSig = useSignificantDigits ? 1 : -1; int32_t maxSig = useSignificantDigits ? 6 : -1; - fields->properties->minimumSignificantDigits = minSig; - fields->properties->maximumSignificantDigits = maxSig; + fields->properties.minimumSignificantDigits = minSig; + fields->properties.maximumSignificantDigits = maxSig; touchNoError(); } @@ -1503,11 +1497,11 @@ void DecimalFormat::setCurrency(const char16_t* theCurrency, UErrorCode& ec) { } CurrencyUnit currencyUnit(theCurrency, ec); if (U_FAILURE(ec)) { return; } - if (!fields->properties->currency.isNull() && fields->properties->currency.getNoError() == currencyUnit) { + if (!fields->properties.currency.isNull() && fields->properties.currency.getNoError() == currencyUnit) { return; } NumberFormat::setCurrency(theCurrency, ec); // to set field for compatibility - fields->properties->currency = currencyUnit; + fields->properties.currency = currencyUnit; // TODO: Set values in fields->symbols, too? touchNoError(); } @@ -1525,20 +1519,20 @@ void DecimalFormat::setCurrencyUsage(UCurrencyUsage newUsage, UErrorCode* ec) { *ec = U_MEMORY_ALLOCATION_ERROR; return; } - if (!fields->properties->currencyUsage.isNull() && newUsage == fields->properties->currencyUsage.getNoError()) { + if (!fields->properties.currencyUsage.isNull() && newUsage == fields->properties.currencyUsage.getNoError()) { return; } - fields->properties->currencyUsage = newUsage; + fields->properties.currencyUsage = newUsage; touch(*ec); } UCurrencyUsage DecimalFormat::getCurrencyUsage() const { // CurrencyUsage is not exported, so we have to get it from the input property bag. // TODO: Should we export CurrencyUsage instead? - if (fields == nullptr || fields->properties->currencyUsage.isNull()) { + if (fields == nullptr || fields->properties.currencyUsage.isNull()) { return UCURR_USAGE_STANDARD; } - return fields->properties->currencyUsage.getNoError(); + return fields->properties.currencyUsage.getNoError(); } void @@ -1550,7 +1544,7 @@ DecimalFormat::formatToDecimalQuantity(double number, DecimalQuantity& output, U status = U_MEMORY_ALLOCATION_ERROR; return; } - fields->formatter->formatDouble(number, status).getDecimalQuantity(output, status); + fields->formatter.formatDouble(number, status).getDecimalQuantity(output, status); } void DecimalFormat::formatToDecimalQuantity(const Formattable& number, DecimalQuantity& output, @@ -1564,7 +1558,7 @@ void DecimalFormat::formatToDecimalQuantity(const Formattable& number, DecimalQu } UFormattedNumberData obj; number.populateDecimalQuantity(obj.quantity, status); - fields->formatter->formatImpl(&obj, status); + fields->formatter.formatImpl(&obj, status); output = std::move(obj.quantity); } @@ -1576,12 +1570,7 @@ const number::LocalizedNumberFormatter* DecimalFormat::toNumberFormatter(UErrorC status = U_MEMORY_ALLOCATION_ERROR; return nullptr; } - return &*fields->formatter; -} - -const number::LocalizedNumberFormatter& DecimalFormat::toNumberFormatter() const { - UErrorCode localStatus = U_ZERO_ERROR; - return *toNumberFormatter(localStatus); + return &fields->formatter; } /** Rebuilds the formatter object from the property bag. */ @@ -1608,9 +1597,9 @@ void DecimalFormat::touch(UErrorCode& status) { // Since memory has already been allocated for the formatter, we can move assign a stack-allocated object // and don't need to call new. (Which is slower and could possibly fail). - *fields->formatter = NumberPropertyMapper::create( - *fields->properties, *fields->symbols, fields->warehouse, *fields->exportedProperties, status).locale( - locale); + fields->formatter = NumberPropertyMapper::create( + fields->properties, *fields->symbols, fields->warehouse, fields->exportedProperties, status + ).locale(locale); // Do this after fields->exportedProperties are set up setupFastFormat(); @@ -1620,13 +1609,13 @@ void DecimalFormat::touch(UErrorCode& status) { delete fields->atomicCurrencyParser.exchange(nullptr); // In order for the getters to work, we need to populate some fields in NumberFormat. - NumberFormat::setCurrency(fields->exportedProperties->currency.get(status).getISOCurrency(), status); - NumberFormat::setMaximumIntegerDigits(fields->exportedProperties->maximumIntegerDigits); - NumberFormat::setMinimumIntegerDigits(fields->exportedProperties->minimumIntegerDigits); - NumberFormat::setMaximumFractionDigits(fields->exportedProperties->maximumFractionDigits); - NumberFormat::setMinimumFractionDigits(fields->exportedProperties->minimumFractionDigits); + NumberFormat::setCurrency(fields->exportedProperties.currency.get(status).getISOCurrency(), status); + NumberFormat::setMaximumIntegerDigits(fields->exportedProperties.maximumIntegerDigits); + NumberFormat::setMinimumIntegerDigits(fields->exportedProperties.minimumIntegerDigits); + NumberFormat::setMaximumFractionDigits(fields->exportedProperties.maximumFractionDigits); + NumberFormat::setMinimumFractionDigits(fields->exportedProperties.minimumFractionDigits); // fImpl->properties, not fields->exportedProperties, since this information comes from the pattern: - NumberFormat::setGroupingUsed(fields->properties->groupingUsed); + NumberFormat::setGroupingUsed(fields->properties.groupingUsed); } void DecimalFormat::touchNoError() { @@ -1639,7 +1628,7 @@ void DecimalFormat::setPropertiesFromPattern(const UnicodeString& pattern, int32 if (U_SUCCESS(status)) { // Cast workaround to get around putting the enum in the public header file auto actualIgnoreRounding = static_cast<IgnoreRounding>(ignoreRounding); - PatternParser::parseToExistingProperties(pattern, *fields->properties, actualIgnoreRounding, status); + PatternParser::parseToExistingProperties(pattern, fields->properties, actualIgnoreRounding, status); } } @@ -1658,7 +1647,7 @@ const numparse::impl::NumberParserImpl* DecimalFormat::getParser(UErrorCode& sta } // Try computing the parser on our own - auto* temp = NumberParserImpl::createParserFromProperties(*fields->properties, *fields->symbols, false, status); + auto* temp = NumberParserImpl::createParserFromProperties(fields->properties, *fields->symbols, false, status); if (U_FAILURE(status)) { return nullptr; } @@ -1691,7 +1680,7 @@ const numparse::impl::NumberParserImpl* DecimalFormat::getCurrencyParser(UErrorC } // Try computing the parser on our own - auto* temp = NumberParserImpl::createParserFromProperties(*fields->properties, *fields->symbols, true, status); + auto* temp = NumberParserImpl::createParserFromProperties(fields->properties, *fields->symbols, true, status); if (temp == nullptr) { status = U_MEMORY_ALLOCATION_ERROR; // although we may still dereference, call sites should be guarded @@ -1739,7 +1728,7 @@ DecimalFormat::fieldPositionIteratorHelper(const number::FormattedNumber& format void DecimalFormat::setupFastFormat() { // Check the majority of properties: - if (!fields->properties->equalsDefaultExceptFastFormat()) { + if (!fields->properties.equalsDefaultExceptFastFormat()) { trace("no fast format: equality\n"); fields->canUseFastFormat = false; return; @@ -1747,12 +1736,12 @@ void DecimalFormat::setupFastFormat() { // Now check the remaining properties. // Nontrivial affixes: - UBool trivialPP = fields->properties->positivePrefixPattern.isEmpty(); - UBool trivialPS = fields->properties->positiveSuffixPattern.isEmpty(); - UBool trivialNP = fields->properties->negativePrefixPattern.isBogus() || ( - fields->properties->negativePrefixPattern.length() == 1 && - fields->properties->negativePrefixPattern.charAt(0) == u'-'); - UBool trivialNS = fields->properties->negativeSuffixPattern.isEmpty(); + UBool trivialPP = fields->properties.positivePrefixPattern.isEmpty(); + UBool trivialPS = fields->properties.positiveSuffixPattern.isEmpty(); + UBool trivialNP = fields->properties.negativePrefixPattern.isBogus() || ( + fields->properties.negativePrefixPattern.length() == 1 && + fields->properties.negativePrefixPattern.charAt(0) == u'-'); + UBool trivialNS = fields->properties.negativeSuffixPattern.isEmpty(); if (!trivialPP || !trivialPS || !trivialNP || !trivialNS) { trace("no fast format: affixes\n"); fields->canUseFastFormat = false; @@ -1760,8 +1749,8 @@ void DecimalFormat::setupFastFormat() { } // Grouping (secondary grouping is forbidden in equalsDefaultExceptFastFormat): - bool groupingUsed = fields->properties->groupingUsed; - int32_t groupingSize = fields->properties->groupingSize; + bool groupingUsed = fields->properties.groupingUsed; + int32_t groupingSize = fields->properties.groupingSize; bool unusualGroupingSize = groupingSize > 0 && groupingSize != 3; const UnicodeString& groupingString = fields->symbols->getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol); if (groupingUsed && (unusualGroupingSize || groupingString.length() != 1)) { @@ -1771,8 +1760,8 @@ void DecimalFormat::setupFastFormat() { } // Integer length: - int32_t minInt = fields->exportedProperties->minimumIntegerDigits; - int32_t maxInt = fields->exportedProperties->maximumIntegerDigits; + int32_t minInt = fields->exportedProperties.minimumIntegerDigits; + int32_t maxInt = fields->exportedProperties.maximumIntegerDigits; // Fastpath supports up to only 10 digits (length of INT32_MIN) if (minInt > 10) { trace("no fast format: integer\n"); @@ -1781,7 +1770,7 @@ void DecimalFormat::setupFastFormat() { } // Fraction length (no fraction part allowed in fast path): - int32_t minFrac = fields->exportedProperties->minimumFractionDigits; + int32_t minFrac = fields->exportedProperties.minimumFractionDigits; if (minFrac > 0) { trace("no fast format: fraction\n"); fields->canUseFastFormat = false; diff --git a/deps/icu-small/source/i18n/double-conversion-bignum-dtoa.cpp b/deps/icu-small/source/i18n/double-conversion-bignum-dtoa.cpp index 2add399f87..a95910df04 100644 --- a/deps/icu-small/source/i18n/double-conversion-bignum-dtoa.cpp +++ b/deps/icu-small/source/i18n/double-conversion-bignum-dtoa.cpp @@ -49,7 +49,7 @@ U_NAMESPACE_BEGIN namespace double_conversion { static int NormalizedExponent(uint64_t significand, int exponent) { - ASSERT(significand != 0); + DOUBLE_CONVERSION_ASSERT(significand != 0); while ((significand & Double::kHiddenBit) == 0) { significand = significand << 1; exponent = exponent - 1; @@ -90,26 +90,26 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator, // Generates 'requested_digits' after the decimal point. static void BignumToFixed(int requested_digits, int* decimal_point, Bignum* numerator, Bignum* denominator, - Vector<char>(buffer), int* length); + Vector<char> buffer, int* length); // Generates 'count' digits of numerator/denominator. // Once 'count' digits have been produced rounds the result depending on the // remainder (remainders of exactly .5 round upwards). Might update the // decimal_point when rounding up (for example for 0.9999). static void GenerateCountedDigits(int count, int* decimal_point, Bignum* numerator, Bignum* denominator, - Vector<char>(buffer), int* length); + Vector<char> buffer, int* length); void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits, Vector<char> buffer, int* length, int* decimal_point) { - ASSERT(v > 0); - ASSERT(!Double(v).IsSpecial()); + DOUBLE_CONVERSION_ASSERT(v > 0); + DOUBLE_CONVERSION_ASSERT(!Double(v).IsSpecial()); uint64_t significand; int exponent; bool lower_boundary_is_closer; if (mode == BIGNUM_DTOA_SHORTEST_SINGLE) { float f = static_cast<float>(v); - ASSERT(f == v); + DOUBLE_CONVERSION_ASSERT(f == v); significand = Single(f).Significand(); exponent = Single(f).Exponent(); lower_boundary_is_closer = Single(f).LowerBoundaryIsCloser(); @@ -148,7 +148,7 @@ void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits, // 4e-324. In this case the denominator needs fewer than 324*4 binary digits. // The maximum double is 1.7976931348623157e308 which needs fewer than // 308*4 binary digits. - ASSERT(Bignum::kMaxSignificantBits >= 324*4); + DOUBLE_CONVERSION_ASSERT(Bignum::kMaxSignificantBits >= 324*4); InitialScaledStartValues(significand, exponent, lower_boundary_is_closer, estimated_power, need_boundary_deltas, &numerator, &denominator, @@ -177,7 +177,7 @@ void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits, buffer, length); break; default: - UNREACHABLE(); + DOUBLE_CONVERSION_UNREACHABLE(); } buffer[*length] = '\0'; } @@ -209,7 +209,7 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator, for (;;) { uint16_t digit; digit = numerator->DivideModuloIntBignum(*denominator); - ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive. + DOUBLE_CONVERSION_ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive. // digit = numerator / denominator (integer division). // numerator = numerator % denominator. buffer[(*length)++] = static_cast<char>(digit + '0'); @@ -255,7 +255,7 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator, // loop would have stopped earlier. // We still have an assert here in case the preconditions were not // satisfied. - ASSERT(buffer[(*length) - 1] != '9'); + DOUBLE_CONVERSION_ASSERT(buffer[(*length) - 1] != '9'); buffer[(*length) - 1]++; } else { // Halfway case. @@ -266,7 +266,7 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator, if ((buffer[(*length) - 1] - '0') % 2 == 0) { // Round down => Do nothing. } else { - ASSERT(buffer[(*length) - 1] != '9'); + DOUBLE_CONVERSION_ASSERT(buffer[(*length) - 1] != '9'); buffer[(*length) - 1]++; } } @@ -278,9 +278,9 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator, // Round up. // Note again that the last digit could not be '9' since this would have // stopped the loop earlier. - // We still have an ASSERT here, in case the preconditions were not + // We still have an DOUBLE_CONVERSION_ASSERT here, in case the preconditions were not // satisfied. - ASSERT(buffer[(*length) -1] != '9'); + DOUBLE_CONVERSION_ASSERT(buffer[(*length) -1] != '9'); buffer[(*length) - 1]++; return; } @@ -297,11 +297,11 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator, static void GenerateCountedDigits(int count, int* decimal_point, Bignum* numerator, Bignum* denominator, Vector<char> buffer, int* length) { - ASSERT(count >= 0); + DOUBLE_CONVERSION_ASSERT(count >= 0); for (int i = 0; i < count - 1; ++i) { uint16_t digit; digit = numerator->DivideModuloIntBignum(*denominator); - ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive. + DOUBLE_CONVERSION_ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive. // digit = numerator / denominator (integer division). // numerator = numerator % denominator. buffer[i] = static_cast<char>(digit + '0'); @@ -314,7 +314,7 @@ static void GenerateCountedDigits(int count, int* decimal_point, if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) { digit++; } - ASSERT(digit <= 10); + DOUBLE_CONVERSION_ASSERT(digit <= 10); buffer[count - 1] = static_cast<char>(digit + '0'); // Correct bad digits (in case we had a sequence of '9's). Propagate the // carry until we hat a non-'9' or til we reach the first digit. @@ -339,7 +339,7 @@ static void GenerateCountedDigits(int count, int* decimal_point, // Input verifies: 1 <= (numerator + delta) / denominator < 10. static void BignumToFixed(int requested_digits, int* decimal_point, Bignum* numerator, Bignum* denominator, - Vector<char>(buffer), int* length) { + Vector<char> buffer, int* length) { // Note that we have to look at more than just the requested_digits, since // a number could be rounded up. Example: v=0.5 with requested_digits=0. // Even though the power of v equals 0 we can't just stop here. @@ -355,7 +355,7 @@ static void BignumToFixed(int requested_digits, int* decimal_point, } else if (-(*decimal_point) == requested_digits) { // We only need to verify if the number rounds down or up. // Ex: 0.04 and 0.06 with requested_digits == 1. - ASSERT(*decimal_point == -requested_digits); + DOUBLE_CONVERSION_ASSERT(*decimal_point == -requested_digits); // Initially the fraction lies in range (1, 10]. Multiply the denominator // by 10 so that we can compare more easily. denominator->Times10(); @@ -434,7 +434,7 @@ static void InitialScaledStartValuesPositiveExponent( Bignum* numerator, Bignum* denominator, Bignum* delta_minus, Bignum* delta_plus) { // A positive exponent implies a positive power. - ASSERT(estimated_power >= 0); + DOUBLE_CONVERSION_ASSERT(estimated_power >= 0); // Since the estimated_power is positive we simply multiply the denominator // by 10^estimated_power. @@ -520,7 +520,7 @@ static void InitialScaledStartValuesNegativeExponentNegativePower( // numerator = v * 10^-estimated_power * 2 * 2^-exponent. // Remember: numerator has been abused as power_ten. So no need to assign it // to itself. - ASSERT(numerator == power_ten); + DOUBLE_CONVERSION_ASSERT(numerator == power_ten); numerator->MultiplyByUInt64(significand); // denominator = 2 * 2^-exponent with exponent < 0. diff --git a/deps/icu-small/source/i18n/double-conversion-bignum.cpp b/deps/icu-small/source/i18n/double-conversion-bignum.cpp index 5356923921..996d75c9f6 100644 --- a/deps/icu-small/source/i18n/double-conversion-bignum.cpp +++ b/deps/icu-small/source/i18n/double-conversion-bignum.cpp @@ -34,6 +34,9 @@ #include "unicode/utypes.h" #if !UCONFIG_NO_FORMATTING +#include <algorithm> +#include <cstring> + // ICU PATCH: Customize header file paths for ICU. #include "double-conversion-bignum.h" @@ -44,136 +47,129 @@ U_NAMESPACE_BEGIN namespace double_conversion { -Bignum::Bignum() - : bigits_buffer_(), bigits_(bigits_buffer_, kBigitCapacity), used_digits_(0), exponent_(0) { - for (int i = 0; i < kBigitCapacity; ++i) { - bigits_[i] = 0; - } +Bignum::Chunk& Bignum::RawBigit(const int index) { + DOUBLE_CONVERSION_ASSERT(static_cast<unsigned>(index) < kBigitCapacity); + return bigits_buffer_[index]; +} + + +const Bignum::Chunk& Bignum::RawBigit(const int index) const { + DOUBLE_CONVERSION_ASSERT(static_cast<unsigned>(index) < kBigitCapacity); + return bigits_buffer_[index]; } template<typename S> -static int BitSize(S value) { +static int BitSize(const S value) { (void) value; // Mark variable as used. return 8 * sizeof(value); } // Guaranteed to lie in one Bigit. -void Bignum::AssignUInt16(uint16_t value) { - ASSERT(kBigitSize >= BitSize(value)); +void Bignum::AssignUInt16(const uint16_t value) { + DOUBLE_CONVERSION_ASSERT(kBigitSize >= BitSize(value)); Zero(); - if (value == 0) return; - - EnsureCapacity(1); - bigits_[0] = value; - used_digits_ = 1; + if (value > 0) { + RawBigit(0) = value; + used_bigits_ = 1; + } } void Bignum::AssignUInt64(uint64_t value) { - const int kUInt64Size = 64; - Zero(); - if (value == 0) return; - - int needed_bigits = kUInt64Size / kBigitSize + 1; - EnsureCapacity(needed_bigits); - for (int i = 0; i < needed_bigits; ++i) { - bigits_[i] = value & kBigitMask; - value = value >> kBigitSize; + for(int i = 0; value > 0; ++i) { + RawBigit(i) = value & kBigitMask; + value >>= kBigitSize; + ++used_bigits_; } - used_digits_ = needed_bigits; - Clamp(); } void Bignum::AssignBignum(const Bignum& other) { exponent_ = other.exponent_; - for (int i = 0; i < other.used_digits_; ++i) { - bigits_[i] = other.bigits_[i]; + for (int i = 0; i < other.used_bigits_; ++i) { + RawBigit(i) = other.RawBigit(i); } - // Clear the excess digits (if there were any). - for (int i = other.used_digits_; i < used_digits_; ++i) { - bigits_[i] = 0; - } - used_digits_ = other.used_digits_; + used_bigits_ = other.used_bigits_; } -static uint64_t ReadUInt64(Vector<const char> buffer, - int from, - int digits_to_read) { +static uint64_t ReadUInt64(const Vector<const char> buffer, + const int from, + const int digits_to_read) { uint64_t result = 0; for (int i = from; i < from + digits_to_read; ++i) { - int digit = buffer[i] - '0'; - ASSERT(0 <= digit && digit <= 9); + const int digit = buffer[i] - '0'; + DOUBLE_CONVERSION_ASSERT(0 <= digit && digit <= 9); result = result * 10 + digit; } return result; } -void Bignum::AssignDecimalString(Vector<const char> value) { +void Bignum::AssignDecimalString(const Vector<const char> value) { // 2^64 = 18446744073709551616 > 10^19 - const int kMaxUint64DecimalDigits = 19; + static const int kMaxUint64DecimalDigits = 19; Zero(); int length = value.length(); - unsigned int pos = 0; + unsigned pos = 0; // Let's just say that each digit needs 4 bits. while (length >= kMaxUint64DecimalDigits) { - uint64_t digits = ReadUInt64(value, pos, kMaxUint64DecimalDigits); + const uint64_t digits = ReadUInt64(value, pos, kMaxUint64DecimalDigits); pos += kMaxUint64DecimalDigits; length -= kMaxUint64DecimalDigits; MultiplyByPowerOfTen(kMaxUint64DecimalDigits); AddUInt64(digits); } - uint64_t digits = ReadUInt64(value, pos, length); + const uint64_t digits = ReadUInt64(value, pos, length); MultiplyByPowerOfTen(length); AddUInt64(digits); Clamp(); } -static int HexCharValue(char c) { - if ('0' <= c && c <= '9') return c - '0'; - if ('a' <= c && c <= 'f') return 10 + c - 'a'; - ASSERT('A' <= c && c <= 'F'); +static uint64_t HexCharValue(const int c) { + if ('0' <= c && c <= '9') { + return c - '0'; + } + if ('a' <= c && c <= 'f') { + return 10 + c - 'a'; + } + DOUBLE_CONVERSION_ASSERT('A' <= c && c <= 'F'); return 10 + c - 'A'; } +// Unlike AssignDecimalString(), this function is "only" used +// for unit-tests and therefore not performance critical. void Bignum::AssignHexString(Vector<const char> value) { Zero(); - int length = value.length(); - - int needed_bigits = length * 4 / kBigitSize + 1; - EnsureCapacity(needed_bigits); - int string_index = length - 1; - for (int i = 0; i < needed_bigits - 1; ++i) { - // These bigits are guaranteed to be "full". - Chunk current_bigit = 0; - for (int j = 0; j < kBigitSize / 4; j++) { - current_bigit += HexCharValue(value[string_index--]) << (j * 4); + // Required capacity could be reduced by ignoring leading zeros. + EnsureCapacity(((value.length() * 4) + kBigitSize - 1) / kBigitSize); + DOUBLE_CONVERSION_ASSERT(sizeof(uint64_t) * 8 >= kBigitSize + 4); // TODO: static_assert + // Accumulates converted hex digits until at least kBigitSize bits. + // Works with non-factor-of-four kBigitSizes. + uint64_t tmp = 0; // Accumulates converted hex digits until at least + for (int cnt = 0; !value.is_empty(); value.pop_back()) { + tmp |= (HexCharValue(value.last()) << cnt); + if ((cnt += 4) >= kBigitSize) { + RawBigit(used_bigits_++) = (tmp & kBigitMask); + cnt -= kBigitSize; + tmp >>= kBigitSize; } - bigits_[i] = current_bigit; - } - used_digits_ = needed_bigits - 1; - - Chunk most_significant_bigit = 0; // Could be = 0; - for (int j = 0; j <= string_index; ++j) { - most_significant_bigit <<= 4; - most_significant_bigit += HexCharValue(value[j]); } - if (most_significant_bigit != 0) { - bigits_[used_digits_] = most_significant_bigit; - used_digits_++; + if (tmp > 0) { + RawBigit(used_bigits_++) = tmp; } Clamp(); } -void Bignum::AddUInt64(uint64_t operand) { - if (operand == 0) return; +void Bignum::AddUInt64(const uint64_t operand) { + if (operand == 0) { + return; + } Bignum other; other.AssignUInt64(operand); AddBignum(other); @@ -181,8 +177,8 @@ void Bignum::AddUInt64(uint64_t operand) { void Bignum::AddBignum(const Bignum& other) { - ASSERT(IsClamped()); - ASSERT(other.IsClamped()); + DOUBLE_CONVERSION_ASSERT(IsClamped()); + DOUBLE_CONVERSION_ASSERT(other.IsClamped()); // If this has a greater exponent than other append zero-bigits to this. // After this call exponent_ <= other.exponent_. @@ -200,48 +196,52 @@ void Bignum::AddBignum(const Bignum& other) { // cccccccccccc 0000 // In both cases we might need a carry bigit. - EnsureCapacity(1 + Max(BigitLength(), other.BigitLength()) - exponent_); + EnsureCapacity(1 + (std::max)(BigitLength(), other.BigitLength()) - exponent_); Chunk carry = 0; int bigit_pos = other.exponent_ - exponent_; - ASSERT(bigit_pos >= 0); - for (int i = 0; i < other.used_digits_; ++i) { - Chunk sum = bigits_[bigit_pos] + other.bigits_[i] + carry; - bigits_[bigit_pos] = sum & kBigitMask; + DOUBLE_CONVERSION_ASSERT(bigit_pos >= 0); + for (int i = used_bigits_; i < bigit_pos; ++i) { + RawBigit(i) = 0; + } + for (int i = 0; i < other.used_bigits_; ++i) { + const Chunk my = (bigit_pos < used_bigits_) ? RawBigit(bigit_pos) : 0; + const Chunk sum = my + other.RawBigit(i) + carry; + RawBigit(bigit_pos) = sum & kBigitMask; carry = sum >> kBigitSize; - bigit_pos++; + ++bigit_pos; } - while (carry != 0) { - Chunk sum = bigits_[bigit_pos] + carry; - bigits_[bigit_pos] = sum & kBigitMask; + const Chunk my = (bigit_pos < used_bigits_) ? RawBigit(bigit_pos) : 0; + const Chunk sum = my + carry; + RawBigit(bigit_pos) = sum & kBigitMask; carry = sum >> kBigitSize; - bigit_pos++; + ++bigit_pos; } - used_digits_ = Max(bigit_pos, used_digits_); - ASSERT(IsClamped()); + used_bigits_ = (std::max)(bigit_pos, static_cast<int>(used_bigits_)); + DOUBLE_CONVERSION_ASSERT(IsClamped()); } void Bignum::SubtractBignum(const Bignum& other) { - ASSERT(IsClamped()); - ASSERT(other.IsClamped()); + DOUBLE_CONVERSION_ASSERT(IsClamped()); + DOUBLE_CONVERSION_ASSERT(other.IsClamped()); // We require this to be bigger than other. - ASSERT(LessEqual(other, *this)); + DOUBLE_CONVERSION_ASSERT(LessEqual(other, *this)); Align(other); - int offset = other.exponent_ - exponent_; + const int offset = other.exponent_ - exponent_; Chunk borrow = 0; int i; - for (i = 0; i < other.used_digits_; ++i) { - ASSERT((borrow == 0) || (borrow == 1)); - Chunk difference = bigits_[i + offset] - other.bigits_[i] - borrow; - bigits_[i + offset] = difference & kBigitMask; + for (i = 0; i < other.used_bigits_; ++i) { + DOUBLE_CONVERSION_ASSERT((borrow == 0) || (borrow == 1)); + const Chunk difference = RawBigit(i + offset) - other.RawBigit(i) - borrow; + RawBigit(i + offset) = difference & kBigitMask; borrow = difference >> (kChunkSize - 1); } while (borrow != 0) { - Chunk difference = bigits_[i + offset] - borrow; - bigits_[i + offset] = difference & kBigitMask; + const Chunk difference = RawBigit(i + offset) - borrow; + RawBigit(i + offset) = difference & kBigitMask; borrow = difference >> (kChunkSize - 1); ++i; } @@ -249,91 +249,105 @@ void Bignum::SubtractBignum(const Bignum& other) { } -void Bignum::ShiftLeft(int shift_amount) { - if (used_digits_ == 0) return; - exponent_ += shift_amount / kBigitSize; - int local_shift = shift_amount % kBigitSize; - EnsureCapacity(used_digits_ + 1); +void Bignum::ShiftLeft(const int shift_amount) { + if (used_bigits_ == 0) { + return; + } + exponent_ += (shift_amount / kBigitSize); + const int local_shift = shift_amount % kBigitSize; + EnsureCapacity(used_bigits_ + 1); BigitsShiftLeft(local_shift); } -void Bignum::MultiplyByUInt32(uint32_t factor) { - if (factor == 1) return; +void Bignum::MultiplyByUInt32(const uint32_t factor) { + if (factor == 1) { + return; + } if (factor == 0) { Zero(); return; } - if (used_digits_ == 0) return; - + if (used_bigits_ == 0) { + return; + } // The product of a bigit with the factor is of size kBigitSize + 32. // Assert that this number + 1 (for the carry) fits into double chunk. - ASSERT(kDoubleChunkSize >= kBigitSize + 32 + 1); + DOUBLE_CONVERSION_ASSERT(kDoubleChunkSize >= kBigitSize + 32 + 1); DoubleChunk carry = 0; - for (int i = 0; i < used_digits_; ++i) { - DoubleChunk product = static_cast<DoubleChunk>(factor) * bigits_[i] + carry; - bigits_[i] = static_cast<Chunk>(product & kBigitMask); + for (int i = 0; i < used_bigits_; ++i) { + const DoubleChunk product = static_cast<DoubleChunk>(factor) * RawBigit(i) + carry; + RawBigit(i) = static_cast<Chunk>(product & kBigitMask); carry = (product >> kBigitSize); } while (carry != 0) { - EnsureCapacity(used_digits_ + 1); - bigits_[used_digits_] = carry & kBigitMask; - used_digits_++; + EnsureCapacity(used_bigits_ + 1); + RawBigit(used_bigits_) = carry & kBigitMask; + used_bigits_++; carry >>= kBigitSize; } } -void Bignum::MultiplyByUInt64(uint64_t factor) { - if (factor == 1) return; +void Bignum::MultiplyByUInt64(const uint64_t factor) { + if (factor == 1) { + return; + } if (factor == 0) { Zero(); return; } - ASSERT(kBigitSize < 32); + if (used_bigits_ == 0) { + return; + } + DOUBLE_CONVERSION_ASSERT(kBigitSize < 32); uint64_t carry = 0; - uint64_t low = factor & 0xFFFFFFFF; - uint64_t high = factor >> 32; - for (int i = 0; i < used_digits_; ++i) { - uint64_t product_low = low * bigits_[i]; - uint64_t product_high = high * bigits_[i]; - uint64_t tmp = (carry & kBigitMask) + product_low; - bigits_[i] = tmp & kBigitMask; + const uint64_t low = factor & 0xFFFFFFFF; + const uint64_t high = factor >> 32; + for (int i = 0; i < used_bigits_; ++i) { + const uint64_t product_low = low * RawBigit(i); + const uint64_t product_high = high * RawBigit(i); + const uint64_t tmp = (carry & kBigitMask) + product_low; + RawBigit(i) = tmp & kBigitMask; carry = (carry >> kBigitSize) + (tmp >> kBigitSize) + (product_high << (32 - kBigitSize)); } while (carry != 0) { - EnsureCapacity(used_digits_ + 1); - bigits_[used_digits_] = carry & kBigitMask; - used_digits_++; + EnsureCapacity(used_bigits_ + 1); + RawBigit(used_bigits_) = carry & kBigitMask; + used_bigits_++; carry >>= kBigitSize; } } -void Bignum::MultiplyByPowerOfTen(int exponent) { - const uint64_t kFive27 = UINT64_2PART_C(0x6765c793, fa10079d); - const uint16_t kFive1 = 5; - const uint16_t kFive2 = kFive1 * 5; - const uint16_t kFive3 = kFive2 * 5; - const uint16_t kFive4 = kFive3 * 5; - const uint16_t kFive5 = kFive4 * 5; - const uint16_t kFive6 = kFive5 * 5; - const uint32_t kFive7 = kFive6 * 5; - const uint32_t kFive8 = kFive7 * 5; - const uint32_t kFive9 = kFive8 * 5; - const uint32_t kFive10 = kFive9 * 5; - const uint32_t kFive11 = kFive10 * 5; - const uint32_t kFive12 = kFive11 * 5; - const uint32_t kFive13 = kFive12 * 5; - const uint32_t kFive1_to_12[] = +void Bignum::MultiplyByPowerOfTen(const int exponent) { + static const uint64_t kFive27 = DOUBLE_CONVERSION_UINT64_2PART_C(0x6765c793, fa10079d); + static const uint16_t kFive1 = 5; + static const uint16_t kFive2 = kFive1 * 5; + static const uint16_t kFive3 = kFive2 * 5; + static const uint16_t kFive4 = kFive3 * 5; + static const uint16_t kFive5 = kFive4 * 5; + static const uint16_t kFive6 = kFive5 * 5; + static const uint32_t kFive7 = kFive6 * 5; + static const uint32_t kFive8 = kFive7 * 5; + static const uint32_t kFive9 = kFive8 * 5; + static const uint32_t kFive10 = kFive9 * 5; + static const uint32_t kFive11 = kFive10 * 5; + static const uint32_t kFive12 = kFive11 * 5; + static const uint32_t kFive13 = kFive12 * 5; + static const uint32_t kFive1_to_12[] = { kFive1, kFive2, kFive3, kFive4, kFive5, kFive6, kFive7, kFive8, kFive9, kFive10, kFive11, kFive12 }; - ASSERT(exponent >= 0); - if (exponent == 0) return; - if (used_digits_ == 0) return; + DOUBLE_CONVERSION_ASSERT(exponent >= 0); + if (exponent == 0) { + return; + } + if (used_bigits_ == 0) { + return; + } // We shift by exponent at the end just before returning. int remaining_exponent = exponent; while (remaining_exponent >= 27) { @@ -352,8 +366,8 @@ void Bignum::MultiplyByPowerOfTen(int exponent) { void Bignum::Square() { - ASSERT(IsClamped()); - int product_length = 2 * used_digits_; + DOUBLE_CONVERSION_ASSERT(IsClamped()); + const int product_length = 2 * used_bigits_; EnsureCapacity(product_length); // Comba multiplication: compute each column separately. @@ -368,64 +382,64 @@ void Bignum::Square() { // // Assert that the additional number of bits in a DoubleChunk are enough to // sum up used_digits of Bigit*Bigit. - if ((1 << (2 * (kChunkSize - kBigitSize))) <= used_digits_) { - UNIMPLEMENTED(); + if ((1 << (2 * (kChunkSize - kBigitSize))) <= used_bigits_) { + DOUBLE_CONVERSION_UNIMPLEMENTED(); } DoubleChunk accumulator = 0; // First shift the digits so we don't overwrite them. - int copy_offset = used_digits_; - for (int i = 0; i < used_digits_; ++i) { - bigits_[copy_offset + i] = bigits_[i]; + const int copy_offset = used_bigits_; + for (int i = 0; i < used_bigits_; ++i) { + RawBigit(copy_offset + i) = RawBigit(i); } // We have two loops to avoid some 'if's in the loop. - for (int i = 0; i < used_digits_; ++i) { + for (int i = 0; i < used_bigits_; ++i) { // Process temporary digit i with power i. // The sum of the two indices must be equal to i. int bigit_index1 = i; int bigit_index2 = 0; // Sum all of the sub-products. while (bigit_index1 >= 0) { - Chunk chunk1 = bigits_[copy_offset + bigit_index1]; - Chunk chunk2 = bigits_[copy_offset + bigit_index2]; + const Chunk chunk1 = RawBigit(copy_offset + bigit_index1); + const Chunk chunk2 = RawBigit(copy_offset + bigit_index2); accumulator += static_cast<DoubleChunk>(chunk1) * chunk2; bigit_index1--; bigit_index2++; } - bigits_[i] = static_cast<Chunk>(accumulator) & kBigitMask; + RawBigit(i) = static_cast<Chunk>(accumulator) & kBigitMask; accumulator >>= kBigitSize; } - for (int i = used_digits_; i < product_length; ++i) { - int bigit_index1 = used_digits_ - 1; + for (int i = used_bigits_; i < product_length; ++i) { + int bigit_index1 = used_bigits_ - 1; int bigit_index2 = i - bigit_index1; // Invariant: sum of both indices is again equal to i. // Inner loop runs 0 times on last iteration, emptying accumulator. - while (bigit_index2 < used_digits_) { - Chunk chunk1 = bigits_[copy_offset + bigit_index1]; - Chunk chunk2 = bigits_[copy_offset + bigit_index2]; + while (bigit_index2 < used_bigits_) { + const Chunk chunk1 = RawBigit(copy_offset + bigit_index1); + const Chunk chunk2 = RawBigit(copy_offset + bigit_index2); accumulator += static_cast<DoubleChunk>(chunk1) * chunk2; bigit_index1--; bigit_index2++; } - // The overwritten bigits_[i] will never be read in further loop iterations, + // The overwritten RawBigit(i) will never be read in further loop iterations, // because bigit_index1 and bigit_index2 are always greater - // than i - used_digits_. - bigits_[i] = static_cast<Chunk>(accumulator) & kBigitMask; + // than i - used_bigits_. + RawBigit(i) = static_cast<Chunk>(accumulator) & kBigitMask; accumulator >>= kBigitSize; } // Since the result was guaranteed to lie inside the number the // accumulator must be 0 now. - ASSERT(accumulator == 0); + DOUBLE_CONVERSION_ASSERT(accumulator == 0); // Don't forget to update the used_digits and the exponent. - used_digits_ = product_length; + used_bigits_ = product_length; exponent_ *= 2; Clamp(); } -void Bignum::AssignPowerUInt16(uint16_t base, int power_exponent) { - ASSERT(base != 0); - ASSERT(power_exponent >= 0); +void Bignum::AssignPowerUInt16(uint16_t base, const int power_exponent) { + DOUBLE_CONVERSION_ASSERT(base != 0); + DOUBLE_CONVERSION_ASSERT(power_exponent >= 0); if (power_exponent == 0) { AssignUInt16(1); return; @@ -445,7 +459,7 @@ void Bignum::AssignPowerUInt16(uint16_t base, int power_exponent) { tmp_base >>= 1; bit_size++; } - int final_size = bit_size * power_exponent; + const int final_size = bit_size * power_exponent; // 1 extra bigit for the shifting, and one for rounded final_size. EnsureCapacity(final_size / kBigitSize + 2); @@ -466,10 +480,10 @@ void Bignum::AssignPowerUInt16(uint16_t base, int power_exponent) { // Verify that there is enough space in this_value to perform the // multiplication. The first bit_size bits must be 0. if ((power_exponent & mask) != 0) { - ASSERT(bit_size > 0); - uint64_t base_bits_mask = - ~((static_cast<uint64_t>(1) << (64 - bit_size)) - 1); - bool high_bits_zero = (this_value & base_bits_mask) == 0; + DOUBLE_CONVERSION_ASSERT(bit_size > 0); + const uint64_t base_bits_mask = + ~((static_cast<uint64_t>(1) << (64 - bit_size)) - 1); + const bool high_bits_zero = (this_value & base_bits_mask) == 0; if (high_bits_zero) { this_value *= base; } else { @@ -499,9 +513,9 @@ void Bignum::AssignPowerUInt16(uint16_t base, int power_exponent) { // Precondition: this/other < 16bit. uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) { - ASSERT(IsClamped()); - ASSERT(other.IsClamped()); - ASSERT(other.used_digits_ > 0); + DOUBLE_CONVERSION_ASSERT(IsClamped()); + DOUBLE_CONVERSION_ASSERT(other.IsClamped()); + DOUBLE_CONVERSION_ASSERT(other.used_bigits_ > 0); // Easy case: if we have less digits than the divisor than the result is 0. // Note: this handles the case where this == 0, too. @@ -519,34 +533,34 @@ uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) { // This naive approach is extremely inefficient if `this` divided by other // is big. This function is implemented for doubleToString where // the result should be small (less than 10). - ASSERT(other.bigits_[other.used_digits_ - 1] >= ((1 << kBigitSize) / 16)); - ASSERT(bigits_[used_digits_ - 1] < 0x10000); + DOUBLE_CONVERSION_ASSERT(other.RawBigit(other.used_bigits_ - 1) >= ((1 << kBigitSize) / 16)); + DOUBLE_CONVERSION_ASSERT(RawBigit(used_bigits_ - 1) < 0x10000); // Remove the multiples of the first digit. // Example this = 23 and other equals 9. -> Remove 2 multiples. - result += static_cast<uint16_t>(bigits_[used_digits_ - 1]); - SubtractTimes(other, bigits_[used_digits_ - 1]); + result += static_cast<uint16_t>(RawBigit(used_bigits_ - 1)); + SubtractTimes(other, RawBigit(used_bigits_ - 1)); } - ASSERT(BigitLength() == other.BigitLength()); + DOUBLE_CONVERSION_ASSERT(BigitLength() == other.BigitLength()); // Both bignums are at the same length now. // Since other has more than 0 digits we know that the access to - // bigits_[used_digits_ - 1] is safe. - Chunk this_bigit = bigits_[used_digits_ - 1]; - Chunk other_bigit = other.bigits_[other.used_digits_ - 1]; + // RawBigit(used_bigits_ - 1) is safe. + const Chunk this_bigit = RawBigit(used_bigits_ - 1); + const Chunk other_bigit = other.RawBigit(other.used_bigits_ - 1); - if (other.used_digits_ == 1) { + if (other.used_bigits_ == 1) { // Shortcut for easy (and common) case. int quotient = this_bigit / other_bigit; - bigits_[used_digits_ - 1] = this_bigit - other_bigit * quotient; - ASSERT(quotient < 0x10000); + RawBigit(used_bigits_ - 1) = this_bigit - other_bigit * quotient; + DOUBLE_CONVERSION_ASSERT(quotient < 0x10000); result += static_cast<uint16_t>(quotient); Clamp(); return result; } - int division_estimate = this_bigit / (other_bigit + 1); - ASSERT(division_estimate < 0x10000); + const int division_estimate = this_bigit / (other_bigit + 1); + DOUBLE_CONVERSION_ASSERT(division_estimate < 0x10000); result += static_cast<uint16_t>(division_estimate); SubtractTimes(other, division_estimate); @@ -566,7 +580,7 @@ uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) { template<typename S> static int SizeInHexChars(S number) { - ASSERT(number > 0); + DOUBLE_CONVERSION_ASSERT(number > 0); int result = 0; while (number != 0) { number >>= 4; @@ -576,29 +590,35 @@ static int SizeInHexChars(S number) { } -static char HexCharOfValue(int value) { - ASSERT(0 <= value && value <= 16); - if (value < 10) return static_cast<char>(value + '0'); +static char HexCharOfValue(const int value) { + DOUBLE_CONVERSION_ASSERT(0 <= value && value <= 16); + if (value < 10) { + return static_cast<char>(value + '0'); + } return static_cast<char>(value - 10 + 'A'); } -bool Bignum::ToHexString(char* buffer, int buffer_size) const { - ASSERT(IsClamped()); +bool Bignum::ToHexString(char* buffer, const int buffer_size) const { + DOUBLE_CONVERSION_ASSERT(IsClamped()); // Each bigit must be printable as separate hex-character. - ASSERT(kBigitSize % 4 == 0); - const int kHexCharsPerBigit = kBigitSize / 4; + DOUBLE_CONVERSION_ASSERT(kBigitSize % 4 == 0); + static const int kHexCharsPerBigit = kBigitSize / 4; - if (used_digits_ == 0) { - if (buffer_size < 2) return false; + if (used_bigits_ == 0) { + if (buffer_size < 2) { + return false; + } buffer[0] = '0'; buffer[1] = '\0'; return true; } // We add 1 for the terminating '\0' character. - int needed_chars = (BigitLength() - 1) * kHexCharsPerBigit + - SizeInHexChars(bigits_[used_digits_ - 1]) + 1; - if (needed_chars > buffer_size) return false; + const int needed_chars = (BigitLength() - 1) * kHexCharsPerBigit + + SizeInHexChars(RawBigit(used_bigits_ - 1)) + 1; + if (needed_chars > buffer_size) { + return false; + } int string_index = needed_chars - 1; buffer[string_index--] = '\0'; for (int i = 0; i < exponent_; ++i) { @@ -606,15 +626,15 @@ bool Bignum::ToHexString(char* buffer, int buffer_size) const { buffer[string_index--] = '0'; } } - for (int i = 0; i < used_digits_ - 1; ++i) { - Chunk current_bigit = bigits_[i]; + for (int i = 0; i < used_bigits_ - 1; ++i) { + Chunk current_bigit = RawBigit(i); for (int j = 0; j < kHexCharsPerBigit; ++j) { buffer[string_index--] = HexCharOfValue(current_bigit & 0xF); current_bigit >>= 4; } } // And finally the last bigit. - Chunk most_significant_bigit = bigits_[used_digits_ - 1]; + Chunk most_significant_bigit = RawBigit(used_bigits_ - 1); while (most_significant_bigit != 0) { buffer[string_index--] = HexCharOfValue(most_significant_bigit & 0xF); most_significant_bigit >>= 4; @@ -623,25 +643,37 @@ bool Bignum::ToHexString(char* buffer, int buffer_size) const { } -Bignum::Chunk Bignum::BigitAt(int index) const { - if (index >= BigitLength()) return 0; - if (index < exponent_) return 0; - return bigits_[index - exponent_]; +Bignum::Chunk Bignum::BigitOrZero(const int index) const { + if (index >= BigitLength()) { + return 0; + } + if (index < exponent_) { + return 0; + } + return RawBigit(index - exponent_); } int Bignum::Compare(const Bignum& a, const Bignum& b) { - ASSERT(a.IsClamped()); - ASSERT(b.IsClamped()); - int bigit_length_a = a.BigitLength(); - int bigit_length_b = b.BigitLength(); - if (bigit_length_a < bigit_length_b) return -1; - if (bigit_length_a > bigit_length_b) return +1; - for (int i = bigit_length_a - 1; i >= Min(a.exponent_, b.exponent_); --i) { - Chunk bigit_a = a.BigitAt(i); - Chunk bigit_b = b.BigitAt(i); - if (bigit_a < bigit_b) return -1; - if (bigit_a > bigit_b) return +1; + DOUBLE_CONVERSION_ASSERT(a.IsClamped()); + DOUBLE_CONVERSION_ASSERT(b.IsClamped()); + const int bigit_length_a = a.BigitLength(); + const int bigit_length_b = b.BigitLength(); + if (bigit_length_a < bigit_length_b) { + return -1; + } + if (bigit_length_a > bigit_length_b) { + return +1; + } + for (int i = bigit_length_a - 1; i >= (std::min)(a.exponent_, b.exponent_); --i) { + const Chunk bigit_a = a.BigitOrZero(i); + const Chunk bigit_b = b.BigitOrZero(i); + if (bigit_a < bigit_b) { + return -1; + } + if (bigit_a > bigit_b) { + return +1; + } // Otherwise they are equal up to this digit. Try the next digit. } return 0; @@ -649,14 +681,18 @@ int Bignum::Compare(const Bignum& a, const Bignum& b) { int Bignum::PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c) { - ASSERT(a.IsClamped()); - ASSERT(b.IsClamped()); - ASSERT(c.IsClamped()); + DOUBLE_CONVERSION_ASSERT(a.IsClamped()); + DOUBLE_CONVERSION_ASSERT(b.IsClamped()); + DOUBLE_CONVERSION_ASSERT(c.IsClamped()); if (a.BigitLength() < b.BigitLength()) { return PlusCompare(b, a, c); } - if (a.BigitLength() + 1 < c.BigitLength()) return -1; - if (a.BigitLength() > c.BigitLength()) return +1; + if (a.BigitLength() + 1 < c.BigitLength()) { + return -1; + } + if (a.BigitLength() > c.BigitLength()) { + return +1; + } // The exponent encodes 0-bigits. So if there are more 0-digits in 'a' than // 'b' has digits, then the bigit-length of 'a'+'b' must be equal to the one // of 'a'. @@ -666,92 +702,83 @@ int Bignum::PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c) { Chunk borrow = 0; // Starting at min_exponent all digits are == 0. So no need to compare them. - int min_exponent = Min(Min(a.exponent_, b.exponent_), c.exponent_); + const int min_exponent = (std::min)((std::min)(a.exponent_, b.exponent_), c.exponent_); for (int i = c.BigitLength() - 1; i >= min_exponent; --i) { - Chunk chunk_a = a.BigitAt(i); - Chunk chunk_b = b.BigitAt(i); - Chunk chunk_c = c.BigitAt(i); - Chunk sum = chunk_a + chunk_b; + const Chunk chunk_a = a.BigitOrZero(i); + const Chunk chunk_b = b.BigitOrZero(i); + const Chunk chunk_c = c.BigitOrZero(i); + const Chunk sum = chunk_a + chunk_b; if (sum > chunk_c + borrow) { return +1; } else { borrow = chunk_c + borrow - sum; - if (borrow > 1) return -1; + if (borrow > 1) { + return -1; + } borrow <<= kBigitSize; } } - if (borrow == 0) return 0; + if (borrow == 0) { + return 0; + } return -1; } void Bignum::Clamp() { - while (used_digits_ > 0 && bigits_[used_digits_ - 1] == 0) { - used_digits_--; + while (used_bigits_ > 0 && RawBigit(used_bigits_ - 1) == 0) { + used_bigits_--; } - if (used_digits_ == 0) { + if (used_bigits_ == 0) { // Zero. exponent_ = 0; } } -bool Bignum::IsClamped() const { - return used_digits_ == 0 || bigits_[used_digits_ - 1] != 0; -} - - -void Bignum::Zero() { - for (int i = 0; i < used_digits_; ++i) { - bigits_[i] = 0; - } - used_digits_ = 0; - exponent_ = 0; -} - - void Bignum::Align(const Bignum& other) { if (exponent_ > other.exponent_) { - // If "X" represents a "hidden" digit (by the exponent) then we are in the + // If "X" represents a "hidden" bigit (by the exponent) then we are in the // following case (a == this, b == other): // a: aaaaaaXXXX or a: aaaaaXXX // b: bbbbbbX b: bbbbbbbbXX // We replace some of the hidden digits (X) of a with 0 digits. // a: aaaaaa000X or a: aaaaa0XX - int zero_digits = exponent_ - other.exponent_; - EnsureCapacity(used_digits_ + zero_digits); - for (int i = used_digits_ - 1; i >= 0; --i) { - bigits_[i + zero_digits] = bigits_[i]; + const int zero_bigits = exponent_ - other.exponent_; + EnsureCapacity(used_bigits_ + zero_bigits); + for (int i = used_bigits_ - 1; i >= 0; --i) { + RawBigit(i + zero_bigits) = RawBigit(i); } - for (int i = 0; i < zero_digits; ++i) { - bigits_[i] = 0; + for (int i = 0; i < zero_bigits; ++i) { + RawBigit(i) = 0; } - used_digits_ += zero_digits; - exponent_ -= zero_digits; - ASSERT(used_digits_ >= 0); - ASSERT(exponent_ >= 0); + used_bigits_ += zero_bigits; + exponent_ -= zero_bigits; + + DOUBLE_CONVERSION_ASSERT(used_bigits_ >= 0); + DOUBLE_CONVERSION_ASSERT(exponent_ >= 0); } } -void Bignum::BigitsShiftLeft(int shift_amount) { - ASSERT(shift_amount < kBigitSize); - ASSERT(shift_amount >= 0); +void Bignum::BigitsShiftLeft(const int shift_amount) { + DOUBLE_CONVERSION_ASSERT(shift_amount < kBigitSize); + DOUBLE_CONVERSION_ASSERT(shift_amount >= 0); Chunk carry = 0; - for (int i = 0; i < used_digits_; ++i) { - Chunk new_carry = bigits_[i] >> (kBigitSize - shift_amount); - bigits_[i] = ((bigits_[i] << shift_amount) + carry) & kBigitMask; + for (int i = 0; i < used_bigits_; ++i) { + const Chunk new_carry = RawBigit(i) >> (kBigitSize - shift_amount); + RawBigit(i) = ((RawBigit(i) << shift_amount) + carry) & kBigitMask; carry = new_carry; } if (carry != 0) { - bigits_[used_digits_] = carry; - used_digits_++; + RawBigit(used_bigits_) = carry; + used_bigits_++; } } -void Bignum::SubtractTimes(const Bignum& other, int factor) { - ASSERT(exponent_ <= other.exponent_); +void Bignum::SubtractTimes(const Bignum& other, const int factor) { + DOUBLE_CONVERSION_ASSERT(exponent_ <= other.exponent_); if (factor < 3) { for (int i = 0; i < factor; ++i) { SubtractBignum(other); @@ -759,19 +786,21 @@ void Bignum::SubtractTimes(const Bignum& other, int factor) { return; } Chunk borrow = 0; - int exponent_diff = other.exponent_ - exponent_; - for (int i = 0; i < other.used_digits_; ++i) { - DoubleChunk product = static_cast<DoubleChunk>(factor) * other.bigits_[i]; - DoubleChunk remove = borrow + product; - Chunk difference = bigits_[i + exponent_diff] - (remove & kBigitMask); - bigits_[i + exponent_diff] = difference & kBigitMask; + const int exponent_diff = other.exponent_ - exponent_; + for (int i = 0; i < other.used_bigits_; ++i) { + const DoubleChunk product = static_cast<DoubleChunk>(factor) * other.RawBigit(i); + const DoubleChunk remove = borrow + product; + const Chunk difference = RawBigit(i + exponent_diff) - (remove & kBigitMask); + RawBigit(i + exponent_diff) = difference & kBigitMask; borrow = static_cast<Chunk>((difference >> (kChunkSize - 1)) + (remove >> kBigitSize)); } - for (int i = other.used_digits_ + exponent_diff; i < used_digits_; ++i) { - if (borrow == 0) return; - Chunk difference = bigits_[i] - borrow; - bigits_[i] = difference & kBigitMask; + for (int i = other.used_bigits_ + exponent_diff; i < used_bigits_; ++i) { + if (borrow == 0) { + return; + } + const Chunk difference = RawBigit(i) - borrow; + RawBigit(i) = difference & kBigitMask; borrow = difference >> (kChunkSize - 1); } Clamp(); diff --git a/deps/icu-small/source/i18n/double-conversion-bignum.h b/deps/icu-small/source/i18n/double-conversion-bignum.h index d39a3dee01..bae900a15a 100644 --- a/deps/icu-small/source/i18n/double-conversion-bignum.h +++ b/deps/icu-small/source/i18n/double-conversion-bignum.h @@ -53,26 +53,27 @@ class Bignum { // exponent. static const int kMaxSignificantBits = 3584; - Bignum(); - void AssignUInt16(uint16_t value); + Bignum() : used_bigits_(0), exponent_(0) {} + + void AssignUInt16(const uint16_t value); void AssignUInt64(uint64_t value); void AssignBignum(const Bignum& other); - void AssignDecimalString(Vector<const char> value); - void AssignHexString(Vector<const char> value); + void AssignDecimalString(const Vector<const char> value); + void AssignHexString(const Vector<const char> value); - void AssignPowerUInt16(uint16_t base, int exponent); + void AssignPowerUInt16(uint16_t base, const int exponent); - void AddUInt64(uint64_t operand); + void AddUInt64(const uint64_t operand); void AddBignum(const Bignum& other); // Precondition: this >= other. void SubtractBignum(const Bignum& other); void Square(); - void ShiftLeft(int shift_amount); - void MultiplyByUInt32(uint32_t factor); - void MultiplyByUInt64(uint64_t factor); - void MultiplyByPowerOfTen(int exponent); + void ShiftLeft(const int shift_amount); + void MultiplyByUInt32(const uint32_t factor); + void MultiplyByUInt64(const uint64_t factor); + void MultiplyByPowerOfTen(const int exponent); void Times10() { return MultiplyByUInt32(10); } // Pseudocode: // int result = this / other; @@ -80,7 +81,7 @@ class Bignum { // In the worst case this function is in O(this/other). uint16_t DivideModuloIntBignum(const Bignum& other); - bool ToHexString(char* buffer, int buffer_size) const; + bool ToHexString(char* buffer, const int buffer_size) const; // Returns // -1 if a < b, @@ -124,33 +125,40 @@ class Bignum { // grow. There are no checks if the stack-allocated space is sufficient. static const int kBigitCapacity = kMaxSignificantBits / kBigitSize; - void EnsureCapacity(int size) { + static void EnsureCapacity(const int size) { if (size > kBigitCapacity) { - UNREACHABLE(); + DOUBLE_CONVERSION_UNREACHABLE(); } } void Align(const Bignum& other); void Clamp(); - bool IsClamped() const; - void Zero(); + bool IsClamped() const { + return used_bigits_ == 0 || RawBigit(used_bigits_ - 1) != 0; + } + void Zero() { + used_bigits_ = 0; + exponent_ = 0; + } // Requires this to have enough capacity (no tests done). - // Updates used_digits_ if necessary. + // Updates used_bigits_ if necessary. // shift_amount must be < kBigitSize. - void BigitsShiftLeft(int shift_amount); - // BigitLength includes the "hidden" digits encoded in the exponent. - int BigitLength() const { return used_digits_ + exponent_; } - Chunk BigitAt(int index) const; - void SubtractTimes(const Bignum& other, int factor); - + void BigitsShiftLeft(const int shift_amount); + // BigitLength includes the "hidden" bigits encoded in the exponent. + int BigitLength() const { return used_bigits_ + exponent_; } + Chunk& RawBigit(const int index); + const Chunk& RawBigit(const int index) const; + Chunk BigitOrZero(const int index) const; + void SubtractTimes(const Bignum& other, const int factor); + + // The Bignum's value is value(bigits_buffer_) * 2^(exponent_ * kBigitSize), + // where the value of the buffer consists of the lower kBigitSize bits of + // the first used_bigits_ Chunks in bigits_buffer_, first chunk has lowest + // significant bits. + int16_t used_bigits_; + int16_t exponent_; Chunk bigits_buffer_[kBigitCapacity]; - // A vector backed by bigits_buffer_. This way accesses to the array are - // checked for out-of-bounds errors. - Vector<Chunk> bigits_; - int used_digits_; - // The Bignum's value equals value(bigits_) * 2^(exponent_ * kBigitSize). - int exponent_; - - DC_DISALLOW_COPY_AND_ASSIGN(Bignum); + + DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(Bignum); }; } // namespace double_conversion diff --git a/deps/icu-small/source/i18n/double-conversion-cached-powers.cpp b/deps/icu-small/source/i18n/double-conversion-cached-powers.cpp index e1b66d2c65..3bc35c8aaf 100644 --- a/deps/icu-small/source/i18n/double-conversion-cached-powers.cpp +++ b/deps/icu-small/source/i18n/double-conversion-cached-powers.cpp @@ -49,6 +49,8 @@ U_NAMESPACE_BEGIN namespace double_conversion { +namespace PowersOfTenCache { + struct CachedPower { uint64_t significand; int16_t binary_exponent; @@ -56,103 +58,99 @@ struct CachedPower { }; static const CachedPower kCachedPowers[] = { - {UINT64_2PART_C(0xfa8fd5a0, 081c0288), -1220, -348}, - {UINT64_2PART_C(0xbaaee17f, a23ebf76), -1193, -340}, - {UINT64_2PART_C(0x8b16fb20, 3055ac76), -1166, -332}, - {UINT64_2PART_C(0xcf42894a, 5dce35ea), -1140, -324}, - {UINT64_2PART_C(0x9a6bb0aa, 55653b2d), -1113, -316}, - {UINT64_2PART_C(0xe61acf03, 3d1a45df), -1087, -308}, - {UINT64_2PART_C(0xab70fe17, c79ac6ca), -1060, -300}, - {UINT64_2PART_C(0xff77b1fc, bebcdc4f), -1034, -292}, - {UINT64_2PART_C(0xbe5691ef, 416bd60c), -1007, -284}, - {UINT64_2PART_C(0x8dd01fad, 907ffc3c), -980, -276}, - {UINT64_2PART_C(0xd3515c28, 31559a83), -954, -268}, - {UINT64_2PART_C(0x9d71ac8f, ada6c9b5), -927, -260}, - {UINT64_2PART_C(0xea9c2277, 23ee8bcb), -901, -252}, - {UINT64_2PART_C(0xaecc4991, 4078536d), -874, -244}, - {UINT64_2PART_C(0x823c1279, 5db6ce57), -847, -236}, - {UINT64_2PART_C(0xc2109436, 4dfb5637), -821, -228}, - {UINT64_2PART_C(0x9096ea6f, 3848984f), -794, -220}, - {UINT64_2PART_C(0xd77485cb, 25823ac7), -768, -212}, - {UINT64_2PART_C(0xa086cfcd, 97bf97f4), -741, -204}, - {UINT64_2PART_C(0xef340a98, 172aace5), -715, -196}, - {UINT64_2PART_C(0xb23867fb, 2a35b28e), -688, -188}, - {UINT64_2PART_C(0x84c8d4df, d2c63f3b), -661, -180}, - {UINT64_2PART_C(0xc5dd4427, 1ad3cdba), -635, -172}, - {UINT64_2PART_C(0x936b9fce, bb25c996), -608, -164}, - {UINT64_2PART_C(0xdbac6c24, 7d62a584), -582, -156}, - {UINT64_2PART_C(0xa3ab6658, 0d5fdaf6), -555, -148}, - {UINT64_2PART_C(0xf3e2f893, dec3f126), -529, -140}, - {UINT64_2PART_C(0xb5b5ada8, aaff80b8), -502, -132}, - {UINT64_2PART_C(0x87625f05, 6c7c4a8b), -475, -124}, - {UINT64_2PART_C(0xc9bcff60, 34c13053), -449, -116}, - {UINT64_2PART_C(0x964e858c, 91ba2655), -422, -108}, - {UINT64_2PART_C(0xdff97724, 70297ebd), -396, -100}, - {UINT64_2PART_C(0xa6dfbd9f, b8e5b88f), -369, -92}, - {UINT64_2PART_C(0xf8a95fcf, 88747d94), -343, -84}, - {UINT64_2PART_C(0xb9447093, 8fa89bcf), -316, -76}, - {UINT64_2PART_C(0x8a08f0f8, bf0f156b), -289, -68}, - {UINT64_2PART_C(0xcdb02555, 653131b6), -263, -60}, - {UINT64_2PART_C(0x993fe2c6, d07b7fac), -236, -52}, - {UINT64_2PART_C(0xe45c10c4, 2a2b3b06), -210, -44}, - {UINT64_2PART_C(0xaa242499, 697392d3), -183, -36}, - {UINT64_2PART_C(0xfd87b5f2, 8300ca0e), -157, -28}, - {UINT64_2PART_C(0xbce50864, 92111aeb), -130, -20}, - {UINT64_2PART_C(0x8cbccc09, 6f5088cc), -103, -12}, - {UINT64_2PART_C(0xd1b71758, e219652c), -77, -4}, - {UINT64_2PART_C(0x9c400000, 00000000), -50, 4}, - {UINT64_2PART_C(0xe8d4a510, 00000000), -24, 12}, - {UINT64_2PART_C(0xad78ebc5, ac620000), 3, 20}, - {UINT64_2PART_C(0x813f3978, f8940984), 30, 28}, - {UINT64_2PART_C(0xc097ce7b, c90715b3), 56, 36}, - {UINT64_2PART_C(0x8f7e32ce, 7bea5c70), 83, 44}, - {UINT64_2PART_C(0xd5d238a4, abe98068), 109, 52}, - {UINT64_2PART_C(0x9f4f2726, 179a2245), 136, 60}, - {UINT64_2PART_C(0xed63a231, d4c4fb27), 162, 68}, - {UINT64_2PART_C(0xb0de6538, 8cc8ada8), 189, 76}, - {UINT64_2PART_C(0x83c7088e, 1aab65db), 216, 84}, - {UINT64_2PART_C(0xc45d1df9, 42711d9a), 242, 92}, - {UINT64_2PART_C(0x924d692c, a61be758), 269, 100}, - {UINT64_2PART_C(0xda01ee64, 1a708dea), 295, 108}, - {UINT64_2PART_C(0xa26da399, 9aef774a), 322, 116}, - {UINT64_2PART_C(0xf209787b, b47d6b85), 348, 124}, - {UINT64_2PART_C(0xb454e4a1, 79dd1877), 375, 132}, - {UINT64_2PART_C(0x865b8692, 5b9bc5c2), 402, 140}, - {UINT64_2PART_C(0xc83553c5, c8965d3d), 428, 148}, - {UINT64_2PART_C(0x952ab45c, fa97a0b3), 455, 156}, - {UINT64_2PART_C(0xde469fbd, 99a05fe3), 481, 164}, - {UINT64_2PART_C(0xa59bc234, db398c25), 508, 172}, - {UINT64_2PART_C(0xf6c69a72, a3989f5c), 534, 180}, - {UINT64_2PART_C(0xb7dcbf53, 54e9bece), 561, 188}, - {UINT64_2PART_C(0x88fcf317, f22241e2), 588, 196}, - {UINT64_2PART_C(0xcc20ce9b, d35c78a5), 614, 204}, - {UINT64_2PART_C(0x98165af3, 7b2153df), 641, 212}, - {UINT64_2PART_C(0xe2a0b5dc, 971f303a), 667, 220}, - {UINT64_2PART_C(0xa8d9d153, 5ce3b396), 694, 228}, - {UINT64_2PART_C(0xfb9b7cd9, a4a7443c), 720, 236}, - {UINT64_2PART_C(0xbb764c4c, a7a44410), 747, 244}, - {UINT64_2PART_C(0x8bab8eef, b6409c1a), 774, 252}, - {UINT64_2PART_C(0xd01fef10, a657842c), 800, 260}, - {UINT64_2PART_C(0x9b10a4e5, e9913129), 827, 268}, - {UINT64_2PART_C(0xe7109bfb, a19c0c9d), 853, 276}, - {UINT64_2PART_C(0xac2820d9, 623bf429), 880, 284}, - {UINT64_2PART_C(0x80444b5e, 7aa7cf85), 907, 292}, - {UINT64_2PART_C(0xbf21e440, 03acdd2d), 933, 300}, - {UINT64_2PART_C(0x8e679c2f, 5e44ff8f), 960, 308}, - {UINT64_2PART_C(0xd433179d, 9c8cb841), 986, 316}, - {UINT64_2PART_C(0x9e19db92, b4e31ba9), 1013, 324}, - {UINT64_2PART_C(0xeb96bf6e, badf77d9), 1039, 332}, - {UINT64_2PART_C(0xaf87023b, 9bf0ee6b), 1066, 340}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xfa8fd5a0, 081c0288), -1220, -348}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xbaaee17f, a23ebf76), -1193, -340}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x8b16fb20, 3055ac76), -1166, -332}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xcf42894a, 5dce35ea), -1140, -324}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x9a6bb0aa, 55653b2d), -1113, -316}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xe61acf03, 3d1a45df), -1087, -308}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xab70fe17, c79ac6ca), -1060, -300}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xff77b1fc, bebcdc4f), -1034, -292}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xbe5691ef, 416bd60c), -1007, -284}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x8dd01fad, 907ffc3c), -980, -276}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xd3515c28, 31559a83), -954, -268}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x9d71ac8f, ada6c9b5), -927, -260}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xea9c2277, 23ee8bcb), -901, -252}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xaecc4991, 4078536d), -874, -244}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x823c1279, 5db6ce57), -847, -236}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xc2109436, 4dfb5637), -821, -228}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x9096ea6f, 3848984f), -794, -220}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xd77485cb, 25823ac7), -768, -212}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xa086cfcd, 97bf97f4), -741, -204}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xef340a98, 172aace5), -715, -196}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xb23867fb, 2a35b28e), -688, -188}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x84c8d4df, d2c63f3b), -661, -180}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xc5dd4427, 1ad3cdba), -635, -172}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x936b9fce, bb25c996), -608, -164}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xdbac6c24, 7d62a584), -582, -156}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xa3ab6658, 0d5fdaf6), -555, -148}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xf3e2f893, dec3f126), -529, -140}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xb5b5ada8, aaff80b8), -502, -132}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x87625f05, 6c7c4a8b), -475, -124}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xc9bcff60, 34c13053), -449, -116}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x964e858c, 91ba2655), -422, -108}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xdff97724, 70297ebd), -396, -100}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xa6dfbd9f, b8e5b88f), -369, -92}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xf8a95fcf, 88747d94), -343, -84}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xb9447093, 8fa89bcf), -316, -76}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x8a08f0f8, bf0f156b), -289, -68}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xcdb02555, 653131b6), -263, -60}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x993fe2c6, d07b7fac), -236, -52}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xe45c10c4, 2a2b3b06), -210, -44}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xaa242499, 697392d3), -183, -36}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xfd87b5f2, 8300ca0e), -157, -28}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xbce50864, 92111aeb), -130, -20}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x8cbccc09, 6f5088cc), -103, -12}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xd1b71758, e219652c), -77, -4}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x9c400000, 00000000), -50, 4}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xe8d4a510, 00000000), -24, 12}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xad78ebc5, ac620000), 3, 20}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x813f3978, f8940984), 30, 28}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xc097ce7b, c90715b3), 56, 36}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x8f7e32ce, 7bea5c70), 83, 44}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xd5d238a4, abe98068), 109, 52}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x9f4f2726, 179a2245), 136, 60}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xed63a231, d4c4fb27), 162, 68}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xb0de6538, 8cc8ada8), 189, 76}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x83c7088e, 1aab65db), 216, 84}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xc45d1df9, 42711d9a), 242, 92}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x924d692c, a61be758), 269, 100}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xda01ee64, 1a708dea), 295, 108}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xa26da399, 9aef774a), 322, 116}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xf209787b, b47d6b85), 348, 124}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xb454e4a1, 79dd1877), 375, 132}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x865b8692, 5b9bc5c2), 402, 140}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xc83553c5, c8965d3d), 428, 148}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x952ab45c, fa97a0b3), 455, 156}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xde469fbd, 99a05fe3), 481, 164}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xa59bc234, db398c25), 508, 172}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xf6c69a72, a3989f5c), 534, 180}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xb7dcbf53, 54e9bece), 561, 188}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x88fcf317, f22241e2), 588, 196}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xcc20ce9b, d35c78a5), 614, 204}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x98165af3, 7b2153df), 641, 212}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xe2a0b5dc, 971f303a), 667, 220}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xa8d9d153, 5ce3b396), 694, 228}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xfb9b7cd9, a4a7443c), 720, 236}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xbb764c4c, a7a44410), 747, 244}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x8bab8eef, b6409c1a), 774, 252}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xd01fef10, a657842c), 800, 260}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x9b10a4e5, e9913129), 827, 268}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xe7109bfb, a19c0c9d), 853, 276}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xac2820d9, 623bf429), 880, 284}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x80444b5e, 7aa7cf85), 907, 292}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xbf21e440, 03acdd2d), 933, 300}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x8e679c2f, 5e44ff8f), 960, 308}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xd433179d, 9c8cb841), 986, 316}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0x9e19db92, b4e31ba9), 1013, 324}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xeb96bf6e, badf77d9), 1039, 332}, + {DOUBLE_CONVERSION_UINT64_2PART_C(0xaf87023b, 9bf0ee6b), 1066, 340}, }; static const int kCachedPowersOffset = 348; // -1 * the first decimal_exponent. static const double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10) -// Difference between the decimal exponents in the table above. -const int PowersOfTenCache::kDecimalExponentDistance = 8; -const int PowersOfTenCache::kMinDecimalExponent = -348; -const int PowersOfTenCache::kMaxDecimalExponent = 340; -void PowersOfTenCache::GetCachedPowerForBinaryExponentRange( +void GetCachedPowerForBinaryExponentRange( int min_exponent, int max_exponent, DiyFp* power, @@ -162,30 +160,32 @@ void PowersOfTenCache::GetCachedPowerForBinaryExponentRange( int foo = kCachedPowersOffset; int index = (foo + static_cast<int>(k) - 1) / kDecimalExponentDistance + 1; - ASSERT(0 <= index && index < static_cast<int>(ARRAY_SIZE(kCachedPowers))); + DOUBLE_CONVERSION_ASSERT(0 <= index && index < static_cast<int>(DOUBLE_CONVERSION_ARRAY_SIZE(kCachedPowers))); CachedPower cached_power = kCachedPowers[index]; - ASSERT(min_exponent <= cached_power.binary_exponent); + DOUBLE_CONVERSION_ASSERT(min_exponent <= cached_power.binary_exponent); (void) max_exponent; // Mark variable as used. - ASSERT(cached_power.binary_exponent <= max_exponent); + DOUBLE_CONVERSION_ASSERT(cached_power.binary_exponent <= max_exponent); *decimal_exponent = cached_power.decimal_exponent; *power = DiyFp(cached_power.significand, cached_power.binary_exponent); } -void PowersOfTenCache::GetCachedPowerForDecimalExponent(int requested_exponent, - DiyFp* power, - int* found_exponent) { - ASSERT(kMinDecimalExponent <= requested_exponent); - ASSERT(requested_exponent < kMaxDecimalExponent + kDecimalExponentDistance); +void GetCachedPowerForDecimalExponent(int requested_exponent, + DiyFp* power, + int* found_exponent) { + DOUBLE_CONVERSION_ASSERT(kMinDecimalExponent <= requested_exponent); + DOUBLE_CONVERSION_ASSERT(requested_exponent < kMaxDecimalExponent + kDecimalExponentDistance); int index = (requested_exponent + kCachedPowersOffset) / kDecimalExponentDistance; CachedPower cached_power = kCachedPowers[index]; *power = DiyFp(cached_power.significand, cached_power.binary_exponent); *found_exponent = cached_power.decimal_exponent; - ASSERT(*found_exponent <= requested_exponent); - ASSERT(requested_exponent < *found_exponent + kDecimalExponentDistance); + DOUBLE_CONVERSION_ASSERT(*found_exponent <= requested_exponent); + DOUBLE_CONVERSION_ASSERT(requested_exponent < *found_exponent + kDecimalExponentDistance); } +} // namespace PowersOfTenCache + } // namespace double_conversion // ICU PATCH: Close ICU namespace diff --git a/deps/icu-small/source/i18n/double-conversion-cached-powers.h b/deps/icu-small/source/i18n/double-conversion-cached-powers.h index 438746b143..ade27baef8 100644 --- a/deps/icu-small/source/i18n/double-conversion-cached-powers.h +++ b/deps/icu-small/source/i18n/double-conversion-cached-powers.h @@ -46,32 +46,32 @@ U_NAMESPACE_BEGIN namespace double_conversion { -class PowersOfTenCache { - public: +namespace PowersOfTenCache { // Not all powers of ten are cached. The decimal exponent of two neighboring // cached numbers will differ by kDecimalExponentDistance. - static const int kDecimalExponentDistance; + static const int kDecimalExponentDistance = 8; - static const int kMinDecimalExponent; - static const int kMaxDecimalExponent; + static const int kMinDecimalExponent = -348; + static const int kMaxDecimalExponent = 340; // Returns a cached power-of-ten with a binary exponent in the range // [min_exponent; max_exponent] (boundaries included). - static void GetCachedPowerForBinaryExponentRange(int min_exponent, - int max_exponent, - DiyFp* power, - int* decimal_exponent); + void GetCachedPowerForBinaryExponentRange(int min_exponent, + int max_exponent, + DiyFp* power, + int* decimal_exponent); // Returns a cached power of ten x ~= 10^k such that // k <= decimal_exponent < k + kCachedPowersDecimalDistance. // The given decimal_exponent must satisfy // kMinDecimalExponent <= requested_exponent, and // requested_exponent < kMaxDecimalExponent + kDecimalExponentDistance. - static void GetCachedPowerForDecimalExponent(int requested_exponent, - DiyFp* power, - int* found_exponent); -}; + void GetCachedPowerForDecimalExponent(int requested_exponent, + DiyFp* power, + int* found_exponent); + +} // namespace PowersOfTenCache } // namespace double_conversion diff --git a/deps/icu-small/source/i18n/double-conversion-diy-fp.cpp b/deps/icu-small/source/i18n/double-conversion-diy-fp.cpp deleted file mode 100644 index f38430c6c3..0000000000 --- a/deps/icu-small/source/i18n/double-conversion-diy-fp.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// © 2018 and later: Unicode, Inc. and others. -// License & terms of use: http://www.unicode.org/copyright.html -// -// From the double-conversion library. Original license: -// -// Copyright 2010 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// ICU PATCH: ifdef around UCONFIG_NO_FORMATTING -#include "unicode/utypes.h" -#if !UCONFIG_NO_FORMATTING - -// ICU PATCH: Customize header file paths for ICU. - -#include "double-conversion-diy-fp.h" -#include "double-conversion-utils.h" - -// ICU PATCH: Wrap in ICU namespace -U_NAMESPACE_BEGIN - -namespace double_conversion { - -void DiyFp::Multiply(const DiyFp& other) { - // Simply "emulates" a 128 bit multiplication. - // However: the resulting number only contains 64 bits. The least - // significant 64 bits are only used for rounding the most significant 64 - // bits. - const uint64_t kM32 = 0xFFFFFFFFU; - uint64_t a = f_ >> 32; - uint64_t b = f_ & kM32; - uint64_t c = other.f_ >> 32; - uint64_t d = other.f_ & kM32; - uint64_t ac = a * c; - uint64_t bc = b * c; - uint64_t ad = a * d; - uint64_t bd = b * d; - uint64_t tmp = (bd >> 32) + (ad & kM32) + (bc & kM32); - // By adding 1U << 31 to tmp we round the final result. - // Halfway cases will be round up. - tmp += 1U << 31; - uint64_t result_f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32); - e_ += other.e_ + 64; - f_ = result_f; -} - -} // namespace double_conversion - -// ICU PATCH: Close ICU namespace -U_NAMESPACE_END -#endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING diff --git a/deps/icu-small/source/i18n/double-conversion-diy-fp.h b/deps/icu-small/source/i18n/double-conversion-diy-fp.h index 21896851d2..5820abedf3 100644 --- a/deps/icu-small/source/i18n/double-conversion-diy-fp.h +++ b/deps/icu-small/source/i18n/double-conversion-diy-fp.h @@ -50,36 +50,55 @@ namespace double_conversion { // with a uint64 significand and an int exponent. Normalized DiyFp numbers will // have the most significant bit of the significand set. // Multiplication and Subtraction do not normalize their results. -// DiyFp are not designed to contain special doubles (NaN and Infinity). +// DiyFp store only non-negative numbers and are not designed to contain special +// doubles (NaN and Infinity). class DiyFp { public: static const int kSignificandSize = 64; DiyFp() : f_(0), e_(0) {} - DiyFp(uint64_t significand, int exponent) : f_(significand), e_(exponent) {} + DiyFp(const uint64_t significand, const int32_t exponent) : f_(significand), e_(exponent) {} - // this = this - other. + // this -= other. // The exponents of both numbers must be the same and the significand of this - // must be bigger than the significand of other. + // must be greater or equal than the significand of other. // The result will not be normalized. void Subtract(const DiyFp& other) { - ASSERT(e_ == other.e_); - ASSERT(f_ >= other.f_); + DOUBLE_CONVERSION_ASSERT(e_ == other.e_); + DOUBLE_CONVERSION_ASSERT(f_ >= other.f_); f_ -= other.f_; } // Returns a - b. - // The exponents of both numbers must be the same and this must be bigger - // than other. The result will not be normalized. + // The exponents of both numbers must be the same and a must be greater + // or equal than b. The result will not be normalized. static DiyFp Minus(const DiyFp& a, const DiyFp& b) { DiyFp result = a; result.Subtract(b); return result; } - - // this = this * other. - void Multiply(const DiyFp& other); + // this *= other. + void Multiply(const DiyFp& other) { + // Simply "emulates" a 128 bit multiplication. + // However: the resulting number only contains 64 bits. The least + // significant 64 bits are only used for rounding the most significant 64 + // bits. + const uint64_t kM32 = 0xFFFFFFFFU; + const uint64_t a = f_ >> 32; + const uint64_t b = f_ & kM32; + const uint64_t c = other.f_ >> 32; + const uint64_t d = other.f_ & kM32; + const uint64_t ac = a * c; + const uint64_t bc = b * c; + const uint64_t ad = a * d; + const uint64_t bd = b * d; + // By adding 1U << 31 to tmp we round the final result. + // Halfway cases will be rounded up. + const uint64_t tmp = (bd >> 32) + (ad & kM32) + (bc & kM32) + (1U << 31); + e_ += other.e_ + 64; + f_ = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32); + } // returns a * b; static DiyFp Times(const DiyFp& a, const DiyFp& b) { @@ -89,13 +108,13 @@ class DiyFp { } void Normalize() { - ASSERT(f_ != 0); + DOUBLE_CONVERSION_ASSERT(f_ != 0); uint64_t significand = f_; - int exponent = e_; + int32_t exponent = e_; - // This method is mainly called for normalizing boundaries. In general - // boundaries need to be shifted by 10 bits. We thus optimize for this case. - const uint64_t k10MSBits = UINT64_2PART_C(0xFFC00000, 00000000); + // This method is mainly called for normalizing boundaries. In general, + // boundaries need to be shifted by 10 bits, and we optimize for this case. + const uint64_t k10MSBits = DOUBLE_CONVERSION_UINT64_2PART_C(0xFFC00000, 00000000); while ((significand & k10MSBits) == 0) { significand <<= 10; exponent -= 10; @@ -115,16 +134,16 @@ class DiyFp { } uint64_t f() const { return f_; } - int e() const { return e_; } + int32_t e() const { return e_; } void set_f(uint64_t new_value) { f_ = new_value; } - void set_e(int new_value) { e_ = new_value; } + void set_e(int32_t new_value) { e_ = new_value; } private: - static const uint64_t kUint64MSB = UINT64_2PART_C(0x80000000, 00000000); + static const uint64_t kUint64MSB = DOUBLE_CONVERSION_UINT64_2PART_C(0x80000000, 00000000); uint64_t f_; - int e_; + int32_t e_; }; } // namespace double_conversion diff --git a/deps/icu-small/source/i18n/double-conversion-double-to-string.cpp b/deps/icu-small/source/i18n/double-conversion-double-to-string.cpp new file mode 100644 index 0000000000..44c176f4f9 --- /dev/null +++ b/deps/icu-small/source/i18n/double-conversion-double-to-string.cpp @@ -0,0 +1,450 @@ +// © 2018 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +// +// From the double-conversion library. Original license: +// +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// ICU PATCH: ifdef around UCONFIG_NO_FORMATTING +#include "unicode/utypes.h" +#if !UCONFIG_NO_FORMATTING + +#include <algorithm> +#include <climits> +#include <cmath> + +// ICU PATCH: Customize header file paths for ICU. +// The file fixed-dtoa.h is not needed. + +#include "double-conversion-double-to-string.h" + +#include "double-conversion-bignum-dtoa.h" +#include "double-conversion-fast-dtoa.h" +#include "double-conversion-ieee.h" +#include "double-conversion-utils.h" + +// ICU PATCH: Wrap in ICU namespace +U_NAMESPACE_BEGIN + +namespace double_conversion { + +#if 0 // not needed for ICU +const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() { + int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN; + static DoubleToStringConverter converter(flags, + "Infinity", + "NaN", + 'e', + -6, 21, + 6, 0); + return converter; +} + + +bool DoubleToStringConverter::HandleSpecialValues( + double value, + StringBuilder* result_builder) const { + Double double_inspect(value); + if (double_inspect.IsInfinite()) { + if (infinity_symbol_ == NULL) return false; + if (value < 0) { + result_builder->AddCharacter('-'); + } + result_builder->AddString(infinity_symbol_); + return true; + } + if (double_inspect.IsNan()) { + if (nan_symbol_ == NULL) return false; + result_builder->AddString(nan_symbol_); + return true; + } + return false; +} + + +void DoubleToStringConverter::CreateExponentialRepresentation( + const char* decimal_digits, + int length, + int exponent, + StringBuilder* result_builder) const { + DOUBLE_CONVERSION_ASSERT(length != 0); + result_builder->AddCharacter(decimal_digits[0]); + if (length != 1) { + result_builder->AddCharacter('.'); + result_builder->AddSubstring(&decimal_digits[1], length-1); + } + result_builder->AddCharacter(exponent_character_); + if (exponent < 0) { + result_builder->AddCharacter('-'); + exponent = -exponent; + } else { + if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) { + result_builder->AddCharacter('+'); + } + } + if (exponent == 0) { + result_builder->AddCharacter('0'); + return; + } + DOUBLE_CONVERSION_ASSERT(exponent < 1e4); + // Changing this constant requires updating the comment of DoubleToStringConverter constructor + const int kMaxExponentLength = 5; + char buffer[kMaxExponentLength + 1]; + buffer[kMaxExponentLength] = '\0'; + int first_char_pos = kMaxExponentLength; + while (exponent > 0) { + buffer[--first_char_pos] = '0' + (exponent % 10); + exponent /= 10; + } + // Add prefix '0' to make exponent width >= min(min_exponent_with_, kMaxExponentLength) + // For example: convert 1e+9 -> 1e+09, if min_exponent_with_ is set to 2 + while(kMaxExponentLength - first_char_pos < std::min(min_exponent_width_, kMaxExponentLength)) { + buffer[--first_char_pos] = '0'; + } + result_builder->AddSubstring(&buffer[first_char_pos], + kMaxExponentLength - first_char_pos); +} + + +void DoubleToStringConverter::CreateDecimalRepresentation( + const char* decimal_digits, + int length, + int decimal_point, + int digits_after_point, + StringBuilder* result_builder) const { + // Create a representation that is padded with zeros if needed. + if (decimal_point <= 0) { + // "0.00000decimal_rep" or "0.000decimal_rep00". + result_builder->AddCharacter('0'); + if (digits_after_point > 0) { + result_builder->AddCharacter('.'); + result_builder->AddPadding('0', -decimal_point); + DOUBLE_CONVERSION_ASSERT(length <= digits_after_point - (-decimal_point)); + result_builder->AddSubstring(decimal_digits, length); + int remaining_digits = digits_after_point - (-decimal_point) - length; + result_builder->AddPadding('0', remaining_digits); + } + } else if (decimal_point >= length) { + // "decimal_rep0000.00000" or "decimal_rep.0000". + result_builder->AddSubstring(decimal_digits, length); + result_builder->AddPadding('0', decimal_point - length); + if (digits_after_point > 0) { + result_builder->AddCharacter('.'); + result_builder->AddPadding('0', digits_after_point); + } + } else { + // "decima.l_rep000". + DOUBLE_CONVERSION_ASSERT(digits_after_point > 0); + result_builder->AddSubstring(decimal_digits, decimal_point); + result_builder->AddCharacter('.'); + DOUBLE_CONVERSION_ASSERT(length - decimal_point <= digits_after_point); + result_builder->AddSubstring(&decimal_digits[decimal_point], + length - decimal_point); + int remaining_digits = digits_after_point - (length - decimal_point); + result_builder->AddPadding('0', remaining_digits); + } + if (digits_after_point == 0) { + if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) { + result_builder->AddCharacter('.'); + } + if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) { + result_builder->AddCharacter('0'); + } + } +} + + +bool DoubleToStringConverter::ToShortestIeeeNumber( + double value, + StringBuilder* result_builder, + DoubleToStringConverter::DtoaMode mode) const { + DOUBLE_CONVERSION_ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE); + if (Double(value).IsSpecial()) { + return HandleSpecialValues(value, result_builder); + } + + int decimal_point; + bool sign; + const int kDecimalRepCapacity = kBase10MaximalLength + 1; + char decimal_rep[kDecimalRepCapacity]; + int decimal_rep_length; + + DoubleToAscii(value, mode, 0, decimal_rep, kDecimalRepCapacity, + &sign, &decimal_rep_length, &decimal_point); + + bool unique_zero = (flags_ & UNIQUE_ZERO) != 0; + if (sign && (value != 0.0 || !unique_zero)) { + result_builder->AddCharacter('-'); + } + + int exponent = decimal_point - 1; + if ((decimal_in_shortest_low_ <= exponent) && + (exponent < decimal_in_shortest_high_)) { + CreateDecimalRepresentation(decimal_rep, decimal_rep_length, + decimal_point, + (std::max)(0, decimal_rep_length - decimal_point), + result_builder); + } else { + CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent, + result_builder); + } + return true; +} + + +bool DoubleToStringConverter::ToFixed(double value, + int requested_digits, + StringBuilder* result_builder) const { + DOUBLE_CONVERSION_ASSERT(kMaxFixedDigitsBeforePoint == 60); + const double kFirstNonFixed = 1e60; + + if (Double(value).IsSpecial()) { + return HandleSpecialValues(value, result_builder); + } + + if (requested_digits > kMaxFixedDigitsAfterPoint) return false; + if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false; + + // Find a sufficiently precise decimal representation of n. + int decimal_point; + bool sign; + // Add space for the '\0' byte. + const int kDecimalRepCapacity = + kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1; + char decimal_rep[kDecimalRepCapacity]; + int decimal_rep_length; + DoubleToAscii(value, FIXED, requested_digits, + decimal_rep, kDecimalRepCapacity, + &sign, &decimal_rep_length, &decimal_point); + + bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); + if (sign && (value != 0.0 || !unique_zero)) { + result_builder->AddCharacter('-'); + } + + CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point, + requested_digits, result_builder); + return true; +} + + +bool DoubleToStringConverter::ToExponential( + double value, + int requested_digits, + StringBuilder* result_builder) const { + if (Double(value).IsSpecial()) { + return HandleSpecialValues(value, result_builder); + } + + if (requested_digits < -1) return false; + if (requested_digits > kMaxExponentialDigits) return false; + + int decimal_point; + bool sign; + // Add space for digit before the decimal point and the '\0' character. + const int kDecimalRepCapacity = kMaxExponentialDigits + 2; + DOUBLE_CONVERSION_ASSERT(kDecimalRepCapacity > kBase10MaximalLength); + char decimal_rep[kDecimalRepCapacity]; +#ifndef NDEBUG + // Problem: there is an assert in StringBuilder::AddSubstring() that + // will pass this buffer to strlen(), and this buffer is not generally + // null-terminated. + memset(decimal_rep, 0, sizeof(decimal_rep)); +#endif + int decimal_rep_length; + + if (requested_digits == -1) { + DoubleToAscii(value, SHORTEST, 0, + decimal_rep, kDecimalRepCapacity, + &sign, &decimal_rep_length, &decimal_point); + } else { + DoubleToAscii(value, PRECISION, requested_digits + 1, + decimal_rep, kDecimalRepCapacity, + &sign, &decimal_rep_length, &decimal_point); + DOUBLE_CONVERSION_ASSERT(decimal_rep_length <= requested_digits + 1); + + for (int i = decimal_rep_length; i < requested_digits + 1; ++i) { + decimal_rep[i] = '0'; + } + decimal_rep_length = requested_digits + 1; + } + + bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); + if (sign && (value != 0.0 || !unique_zero)) { + result_builder->AddCharacter('-'); + } + + int exponent = decimal_point - 1; + CreateExponentialRepresentation(decimal_rep, + decimal_rep_length, + exponent, + result_builder); + return true; +} + + +bool DoubleToStringConverter::ToPrecision(double value, + int precision, + StringBuilder* result_builder) const { + if (Double(value).IsSpecial()) { + return HandleSpecialValues(value, result_builder); + } + + if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) { + return false; + } + + // Find a sufficiently precise decimal representation of n. + int decimal_point; + bool sign; + // Add one for the terminating null character. + const int kDecimalRepCapacity = kMaxPrecisionDigits + 1; + char decimal_rep[kDecimalRepCapacity]; + int decimal_rep_length; + + DoubleToAscii(value, PRECISION, precision, + decimal_rep, kDecimalRepCapacity, + &sign, &decimal_rep_length, &decimal_point); + DOUBLE_CONVERSION_ASSERT(decimal_rep_length <= precision); + + bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); + if (sign && (value != 0.0 || !unique_zero)) { + result_builder->AddCharacter('-'); + } + + // The exponent if we print the number as x.xxeyyy. That is with the + // decimal point after the first digit. + int exponent = decimal_point - 1; + + int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0; + if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) || + (decimal_point - precision + extra_zero > + max_trailing_padding_zeroes_in_precision_mode_)) { + // Fill buffer to contain 'precision' digits. + // Usually the buffer is already at the correct length, but 'DoubleToAscii' + // is allowed to return less characters. + for (int i = decimal_rep_length; i < precision; ++i) { + decimal_rep[i] = '0'; + } + + CreateExponentialRepresentation(decimal_rep, + precision, + exponent, + result_builder); + } else { + CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point, + (std::max)(0, precision - decimal_point), + result_builder); + } + return true; +} +#endif // not needed for ICU + + +static BignumDtoaMode DtoaToBignumDtoaMode( + DoubleToStringConverter::DtoaMode dtoa_mode) { + switch (dtoa_mode) { + case DoubleToStringConverter::SHORTEST: return BIGNUM_DTOA_SHORTEST; + case DoubleToStringConverter::SHORTEST_SINGLE: + return BIGNUM_DTOA_SHORTEST_SINGLE; + case DoubleToStringConverter::FIXED: return BIGNUM_DTOA_FIXED; + case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION; + default: + DOUBLE_CONVERSION_UNREACHABLE(); + } +} + + +void DoubleToStringConverter::DoubleToAscii(double v, + DtoaMode mode, + int requested_digits, + char* buffer, + int buffer_length, + bool* sign, + int* length, + int* point) { + Vector<char> vector(buffer, buffer_length); + DOUBLE_CONVERSION_ASSERT(!Double(v).IsSpecial()); + DOUBLE_CONVERSION_ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE || requested_digits >= 0); + + if (Double(v).Sign() < 0) { + *sign = true; + v = -v; + } else { + *sign = false; + } + + if (mode == PRECISION && requested_digits == 0) { + vector[0] = '\0'; + *length = 0; + return; + } + + if (v == 0) { + vector[0] = '0'; + vector[1] = '\0'; + *length = 1; + *point = 1; + return; + } + + bool fast_worked; + switch (mode) { + case SHORTEST: + fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point); + break; +#if 0 // not needed for ICU + case SHORTEST_SINGLE: + fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0, + vector, length, point); + break; + case FIXED: + fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point); + break; + case PRECISION: + fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits, + vector, length, point); + break; +#endif // not needed for ICU + default: + fast_worked = false; + DOUBLE_CONVERSION_UNREACHABLE(); + } + if (fast_worked) return; + + // If the fast dtoa didn't succeed use the slower bignum version. + BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode); + BignumDtoa(v, bignum_mode, requested_digits, vector, length, point); + vector[*length] = '\0'; +} + +} // namespace double_conversion + +// ICU PATCH: Close ICU namespace +U_NAMESPACE_END +#endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING diff --git a/deps/icu-small/source/i18n/double-conversion-double-to-string.h b/deps/icu-small/source/i18n/double-conversion-double-to-string.h new file mode 100644 index 0000000000..27bd867848 --- /dev/null +++ b/deps/icu-small/source/i18n/double-conversion-double-to-string.h @@ -0,0 +1,419 @@ +// © 2018 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +// +// From the double-conversion library. Original license: +// +// Copyright 2012 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// ICU PATCH: ifdef around UCONFIG_NO_FORMATTING +#include "unicode/utypes.h" +#if !UCONFIG_NO_FORMATTING + +#ifndef DOUBLE_CONVERSION_DOUBLE_TO_STRING_H_ +#define DOUBLE_CONVERSION_DOUBLE_TO_STRING_H_ + +// ICU PATCH: Customize header file paths for ICU. + +#include "double-conversion-utils.h" + +// ICU PATCH: Wrap in ICU namespace +U_NAMESPACE_BEGIN + +namespace double_conversion { + +class DoubleToStringConverter { + public: +#if 0 // not needed for ICU + // When calling ToFixed with a double > 10^kMaxFixedDigitsBeforePoint + // or a requested_digits parameter > kMaxFixedDigitsAfterPoint then the + // function returns false. + static const int kMaxFixedDigitsBeforePoint = 60; + static const int kMaxFixedDigitsAfterPoint = 60; + + // When calling ToExponential with a requested_digits + // parameter > kMaxExponentialDigits then the function returns false. + static const int kMaxExponentialDigits = 120; + + // When calling ToPrecision with a requested_digits + // parameter < kMinPrecisionDigits or requested_digits > kMaxPrecisionDigits + // then the function returns false. + static const int kMinPrecisionDigits = 1; + static const int kMaxPrecisionDigits = 120; + + enum Flags { + NO_FLAGS = 0, + EMIT_POSITIVE_EXPONENT_SIGN = 1, + EMIT_TRAILING_DECIMAL_POINT = 2, + EMIT_TRAILING_ZERO_AFTER_POINT = 4, + UNIQUE_ZERO = 8 + }; + + // Flags should be a bit-or combination of the possible Flags-enum. + // - NO_FLAGS: no special flags. + // - EMIT_POSITIVE_EXPONENT_SIGN: when the number is converted into exponent + // form, emits a '+' for positive exponents. Example: 1.2e+2. + // - EMIT_TRAILING_DECIMAL_POINT: when the input number is an integer and is + // converted into decimal format then a trailing decimal point is appended. + // Example: 2345.0 is converted to "2345.". + // - EMIT_TRAILING_ZERO_AFTER_POINT: in addition to a trailing decimal point + // emits a trailing '0'-character. This flag requires the + // EXMIT_TRAILING_DECIMAL_POINT flag. + // Example: 2345.0 is converted to "2345.0". + // - UNIQUE_ZERO: "-0.0" is converted to "0.0". + // + // Infinity symbol and nan_symbol provide the string representation for these + // special values. If the string is NULL and the special value is encountered + // then the conversion functions return false. + // + // The exponent_character is used in exponential representations. It is + // usually 'e' or 'E'. + // + // When converting to the shortest representation the converter will + // represent input numbers in decimal format if they are in the interval + // [10^decimal_in_shortest_low; 10^decimal_in_shortest_high[ + // (lower boundary included, greater boundary excluded). + // Example: with decimal_in_shortest_low = -6 and + // decimal_in_shortest_high = 21: + // ToShortest(0.000001) -> "0.000001" + // ToShortest(0.0000001) -> "1e-7" + // ToShortest(111111111111111111111.0) -> "111111111111111110000" + // ToShortest(100000000000000000000.0) -> "100000000000000000000" + // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21" + // + // When converting to precision mode the converter may add + // max_leading_padding_zeroes before returning the number in exponential + // format. + // Example with max_leading_padding_zeroes_in_precision_mode = 6. + // ToPrecision(0.0000012345, 2) -> "0.0000012" + // ToPrecision(0.00000012345, 2) -> "1.2e-7" + // Similarily the converter may add up to + // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid + // returning an exponential representation. A zero added by the + // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit. + // Examples for max_trailing_padding_zeroes_in_precision_mode = 1: + // ToPrecision(230.0, 2) -> "230" + // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT. + // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT. + // + // The min_exponent_width is used for exponential representations. + // The converter adds leading '0's to the exponent until the exponent + // is at least min_exponent_width digits long. + // The min_exponent_width is clamped to 5. + // As such, the exponent may never have more than 5 digits in total. + DoubleToStringConverter(int flags, + const char* infinity_symbol, + const char* nan_symbol, + char exponent_character, + int decimal_in_shortest_low, + int decimal_in_shortest_high, + int max_leading_padding_zeroes_in_precision_mode, + int max_trailing_padding_zeroes_in_precision_mode, + int min_exponent_width = 0) + : flags_(flags), + infinity_symbol_(infinity_symbol), + nan_symbol_(nan_symbol), + exponent_character_(exponent_character), + decimal_in_shortest_low_(decimal_in_shortest_low), + decimal_in_shortest_high_(decimal_in_shortest_high), + max_leading_padding_zeroes_in_precision_mode_( + max_leading_padding_zeroes_in_precision_mode), + max_trailing_padding_zeroes_in_precision_mode_( + max_trailing_padding_zeroes_in_precision_mode), + min_exponent_width_(min_exponent_width) { + // When 'trailing zero after the point' is set, then 'trailing point' + // must be set too. + DOUBLE_CONVERSION_ASSERT(((flags & EMIT_TRAILING_DECIMAL_POINT) != 0) || + !((flags & EMIT_TRAILING_ZERO_AFTER_POINT) != 0)); + } + + // Returns a converter following the EcmaScript specification. + static const DoubleToStringConverter& EcmaScriptConverter(); + + // Computes the shortest string of digits that correctly represent the input + // number. Depending on decimal_in_shortest_low and decimal_in_shortest_high + // (see constructor) it then either returns a decimal representation, or an + // exponential representation. + // Example with decimal_in_shortest_low = -6, + // decimal_in_shortest_high = 21, + // EMIT_POSITIVE_EXPONENT_SIGN activated, and + // EMIT_TRAILING_DECIMAL_POINT deactived: + // ToShortest(0.000001) -> "0.000001" + // ToShortest(0.0000001) -> "1e-7" + // ToShortest(111111111111111111111.0) -> "111111111111111110000" + // ToShortest(100000000000000000000.0) -> "100000000000000000000" + // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21" + // + // Note: the conversion may round the output if the returned string + // is accurate enough to uniquely identify the input-number. + // For example the most precise representation of the double 9e59 equals + // "899999999999999918767229449717619953810131273674690656206848", but + // the converter will return the shorter (but still correct) "9e59". + // + // Returns true if the conversion succeeds. The conversion always succeeds + // except when the input value is special and no infinity_symbol or + // nan_symbol has been given to the constructor. + bool ToShortest(double value, StringBuilder* result_builder) const { + return ToShortestIeeeNumber(value, result_builder, SHORTEST); + } + + // Same as ToShortest, but for single-precision floats. + bool ToShortestSingle(float value, StringBuilder* result_builder) const { + return ToShortestIeeeNumber(value, result_builder, SHORTEST_SINGLE); + } + + + // Computes a decimal representation with a fixed number of digits after the + // decimal point. The last emitted digit is rounded. + // + // Examples: + // ToFixed(3.12, 1) -> "3.1" + // ToFixed(3.1415, 3) -> "3.142" + // ToFixed(1234.56789, 4) -> "1234.5679" + // ToFixed(1.23, 5) -> "1.23000" + // ToFixed(0.1, 4) -> "0.1000" + // ToFixed(1e30, 2) -> "1000000000000000019884624838656.00" + // ToFixed(0.1, 30) -> "0.100000000000000005551115123126" + // ToFixed(0.1, 17) -> "0.10000000000000001" + // + // If requested_digits equals 0, then the tail of the result depends on + // the EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT. + // Examples, for requested_digits == 0, + // let EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT be + // - false and false: then 123.45 -> 123 + // 0.678 -> 1 + // - true and false: then 123.45 -> 123. + // 0.678 -> 1. + // - true and true: then 123.45 -> 123.0 + // 0.678 -> 1.0 + // + // Returns true if the conversion succeeds. The conversion always succeeds + // except for the following cases: + // - the input value is special and no infinity_symbol or nan_symbol has + // been provided to the constructor, + // - 'value' > 10^kMaxFixedDigitsBeforePoint, or + // - 'requested_digits' > kMaxFixedDigitsAfterPoint. + // The last two conditions imply that the result will never contain more than + // 1 + kMaxFixedDigitsBeforePoint + 1 + kMaxFixedDigitsAfterPoint characters + // (one additional character for the sign, and one for the decimal point). + bool ToFixed(double value, + int requested_digits, + StringBuilder* result_builder) const; + + // Computes a representation in exponential format with requested_digits + // after the decimal point. The last emitted digit is rounded. + // If requested_digits equals -1, then the shortest exponential representation + // is computed. + // + // Examples with EMIT_POSITIVE_EXPONENT_SIGN deactivated, and + // exponent_character set to 'e'. + // ToExponential(3.12, 1) -> "3.1e0" + // ToExponential(5.0, 3) -> "5.000e0" + // ToExponential(0.001, 2) -> "1.00e-3" + // ToExponential(3.1415, -1) -> "3.1415e0" + // ToExponential(3.1415, 4) -> "3.1415e0" + // ToExponential(3.1415, 3) -> "3.142e0" + // ToExponential(123456789000000, 3) -> "1.235e14" + // ToExponential(1000000000000000019884624838656.0, -1) -> "1e30" + // ToExponential(1000000000000000019884624838656.0, 32) -> + // "1.00000000000000001988462483865600e30" + // ToExponential(1234, 0) -> "1e3" + // + // Returns true if the conversion succeeds. The conversion always succeeds + // except for the following cases: + // - the input value is special and no infinity_symbol or nan_symbol has + // been provided to the constructor, + // - 'requested_digits' > kMaxExponentialDigits. + // The last condition implies that the result will never contain more than + // kMaxExponentialDigits + 8 characters (the sign, the digit before the + // decimal point, the decimal point, the exponent character, the + // exponent's sign, and at most 3 exponent digits). + bool ToExponential(double value, + int requested_digits, + StringBuilder* result_builder) const; + + // Computes 'precision' leading digits of the given 'value' and returns them + // either in exponential or decimal format, depending on + // max_{leading|trailing}_padding_zeroes_in_precision_mode (given to the + // constructor). + // The last computed digit is rounded. + // + // Example with max_leading_padding_zeroes_in_precision_mode = 6. + // ToPrecision(0.0000012345, 2) -> "0.0000012" + // ToPrecision(0.00000012345, 2) -> "1.2e-7" + // Similarily the converter may add up to + // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid + // returning an exponential representation. A zero added by the + // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit. + // Examples for max_trailing_padding_zeroes_in_precision_mode = 1: + // ToPrecision(230.0, 2) -> "230" + // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT. + // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT. + // Examples for max_trailing_padding_zeroes_in_precision_mode = 3, and no + // EMIT_TRAILING_ZERO_AFTER_POINT: + // ToPrecision(123450.0, 6) -> "123450" + // ToPrecision(123450.0, 5) -> "123450" + // ToPrecision(123450.0, 4) -> "123500" + // ToPrecision(123450.0, 3) -> "123000" + // ToPrecision(123450.0, 2) -> "1.2e5" + // + // Returns true if the conversion succeeds. The conversion always succeeds + // except for the following cases: + // - the input value is special and no infinity_symbol or nan_symbol has + // been provided to the constructor, + // - precision < kMinPericisionDigits + // - precision > kMaxPrecisionDigits + // The last condition implies that the result will never contain more than + // kMaxPrecisionDigits + 7 characters (the sign, the decimal point, the + // exponent character, the exponent's sign, and at most 3 exponent digits). + bool ToPrecision(double value, + int precision, + StringBuilder* result_builder) const; +#endif // not needed for ICU + + enum DtoaMode { + // Produce the shortest correct representation. + // For example the output of 0.299999999999999988897 is (the less accurate + // but correct) 0.3. + SHORTEST, + // Same as SHORTEST, but for single-precision floats. + SHORTEST_SINGLE, + // Produce a fixed number of digits after the decimal point. + // For instance fixed(0.1, 4) becomes 0.1000 + // If the input number is big, the output will be big. + FIXED, + // Fixed number of digits (independent of the decimal point). + PRECISION + }; + + // The maximal number of digits that are needed to emit a double in base 10. + // A higher precision can be achieved by using more digits, but the shortest + // accurate representation of any double will never use more digits than + // kBase10MaximalLength. + // Note that DoubleToAscii null-terminates its input. So the given buffer + // should be at least kBase10MaximalLength + 1 characters long. + static const int kBase10MaximalLength = 17; + + // Converts the given double 'v' to digit characters. 'v' must not be NaN, + // +Infinity, or -Infinity. In SHORTEST_SINGLE-mode this restriction also + // applies to 'v' after it has been casted to a single-precision float. That + // is, in this mode static_cast<float>(v) must not be NaN, +Infinity or + // -Infinity. + // + // The result should be interpreted as buffer * 10^(point-length). + // + // The digits are written to the buffer in the platform's charset, which is + // often UTF-8 (with ASCII-range digits) but may be another charset, such + // as EBCDIC. + // + // The output depends on the given mode: + // - SHORTEST: produce the least amount of digits for which the internal + // identity requirement is still satisfied. If the digits are printed + // (together with the correct exponent) then reading this number will give + // 'v' again. The buffer will choose the representation that is closest to + // 'v'. If there are two at the same distance, than the one farther away + // from 0 is chosen (halfway cases - ending with 5 - are rounded up). + // In this mode the 'requested_digits' parameter is ignored. + // - SHORTEST_SINGLE: same as SHORTEST but with single-precision. + // - FIXED: produces digits necessary to print a given number with + // 'requested_digits' digits after the decimal point. The produced digits + // might be too short in which case the caller has to fill the remainder + // with '0's. + // Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2. + // Halfway cases are rounded towards +/-Infinity (away from 0). The call + // toFixed(0.15, 2) thus returns buffer="2", point=0. + // The returned buffer may contain digits that would be truncated from the + // shortest representation of the input. + // - PRECISION: produces 'requested_digits' where the first digit is not '0'. + // Even though the length of produced digits usually equals + // 'requested_digits', the function is allowed to return fewer digits, in + // which case the caller has to fill the missing digits with '0's. + // Halfway cases are again rounded away from 0. + // DoubleToAscii expects the given buffer to be big enough to hold all + // digits and a terminating null-character. In SHORTEST-mode it expects a + // buffer of at least kBase10MaximalLength + 1. In all other modes the + // requested_digits parameter and the padding-zeroes limit the size of the + // output. Don't forget the decimal point, the exponent character and the + // terminating null-character when computing the maximal output size. + // The given length is only used in debug mode to ensure the buffer is big + // enough. + // ICU PATCH: Export this as U_I18N_API for unit tests. + static void U_I18N_API DoubleToAscii(double v, + DtoaMode mode, + int requested_digits, + char* buffer, + int buffer_length, + bool* sign, + int* length, + int* point); + +#if 0 // not needed for ICU + private: + // Implementation for ToShortest and ToShortestSingle. + bool ToShortestIeeeNumber(double value, + StringBuilder* result_builder, + DtoaMode mode) const; + + // If the value is a special value (NaN or Infinity) constructs the + // corresponding string using the configured infinity/nan-symbol. + // If either of them is NULL or the value is not special then the + // function returns false. + bool HandleSpecialValues(double value, StringBuilder* result_builder) const; + // Constructs an exponential representation (i.e. 1.234e56). + // The given exponent assumes a decimal point after the first decimal digit. + void CreateExponentialRepresentation(const char* decimal_digits, + int length, + int exponent, + StringBuilder* result_builder) const; + // Creates a decimal representation (i.e 1234.5678). + void CreateDecimalRepresentation(const char* decimal_digits, + int length, + int decimal_point, + int digits_after_point, + StringBuilder* result_builder) const; + + const int flags_; + const char* const infinity_symbol_; + const char* const nan_symbol_; + const char exponent_character_; + const int decimal_in_shortest_low_; + const int decimal_in_shortest_high_; + const int max_leading_padding_zeroes_in_precision_mode_; + const int max_trailing_padding_zeroes_in_precision_mode_; + const int min_exponent_width_; +#endif // not needed for ICU + + DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter); +}; + +} // namespace double_conversion + +// ICU PATCH: Close ICU namespace +U_NAMESPACE_END + +#endif // DOUBLE_CONVERSION_DOUBLE_TO_STRING_H_ +#endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING diff --git a/deps/icu-small/source/i18n/double-conversion-fast-dtoa.cpp b/deps/icu-small/source/i18n/double-conversion-fast-dtoa.cpp index 8d1499a79b..87a3d536bf 100644 --- a/deps/icu-small/source/i18n/double-conversion-fast-dtoa.cpp +++ b/deps/icu-small/source/i18n/double-conversion-fast-dtoa.cpp @@ -152,7 +152,7 @@ static bool RoundWeed(Vector<char> buffer, // Conceptually rest ~= too_high - buffer // We need to do the following tests in this order to avoid over- and // underflows. - ASSERT(rest <= unsafe_interval); + DOUBLE_CONVERSION_ASSERT(rest <= unsafe_interval); while (rest < small_distance && // Negated condition 1 unsafe_interval - rest >= ten_kappa && // Negated condition 2 (rest + ten_kappa < small_distance || // buffer{-1} > w_high @@ -198,7 +198,7 @@ static bool RoundWeedCounted(Vector<char> buffer, uint64_t ten_kappa, uint64_t unit, int* kappa) { - ASSERT(rest < ten_kappa); + DOUBLE_CONVERSION_ASSERT(rest < ten_kappa); // The following tests are done in a specific order to avoid overflows. They // will work correctly with any uint64 values of rest < ten_kappa and unit. // @@ -255,7 +255,7 @@ static void BiggestPowerTen(uint32_t number, int number_bits, uint32_t* power, int* exponent_plus_one) { - ASSERT(number < (1u << (number_bits + 1))); + DOUBLE_CONVERSION_ASSERT(number < (1u << (number_bits + 1))); // 1233/4096 is approximately 1/lg(10). int exponent_plus_one_guess = ((number_bits + 1) * 1233 >> 12); // We increment to skip over the first entry in the kPowersOf10 table. @@ -317,9 +317,9 @@ static bool DigitGen(DiyFp low, Vector<char> buffer, int* length, int* kappa) { - ASSERT(low.e() == w.e() && w.e() == high.e()); - ASSERT(low.f() + 1 <= high.f() - 1); - ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent); + DOUBLE_CONVERSION_ASSERT(low.e() == w.e() && w.e() == high.e()); + DOUBLE_CONVERSION_ASSERT(low.f() + 1 <= high.f() - 1); + DOUBLE_CONVERSION_ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent); // low, w and high are imprecise, but by less than one ulp (unit in the last // place). // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that @@ -361,7 +361,7 @@ static bool DigitGen(DiyFp low, // that is smaller than integrals. while (*kappa > 0) { int digit = integrals / divisor; - ASSERT(digit <= 9); + DOUBLE_CONVERSION_ASSERT(digit <= 9); buffer[*length] = static_cast<char>('0' + digit); (*length)++; integrals %= divisor; @@ -388,16 +388,16 @@ static bool DigitGen(DiyFp low, // data (like the interval or 'unit'), too. // Note that the multiplication by 10 does not overflow, because w.e >= -60 // and thus one.e >= -60. - ASSERT(one.e() >= -60); - ASSERT(fractionals < one.f()); - ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f()); + DOUBLE_CONVERSION_ASSERT(one.e() >= -60); + DOUBLE_CONVERSION_ASSERT(fractionals < one.f()); + DOUBLE_CONVERSION_ASSERT(DOUBLE_CONVERSION_UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f()); for (;;) { fractionals *= 10; unit *= 10; unsafe_interval.set_f(unsafe_interval.f() * 10); // Integer division by one. int digit = static_cast<int>(fractionals >> -one.e()); - ASSERT(digit <= 9); + DOUBLE_CONVERSION_ASSERT(digit <= 9); buffer[*length] = static_cast<char>('0' + digit); (*length)++; fractionals &= one.f() - 1; // Modulo by one. @@ -444,9 +444,9 @@ static bool DigitGenCounted(DiyFp w, Vector<char> buffer, int* length, int* kappa) { - ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent); - ASSERT(kMinimalTargetExponent >= -60); - ASSERT(kMaximalTargetExponent <= -32); + DOUBLE_CONVERSION_ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent); + DOUBLE_CONVERSION_ASSERT(kMinimalTargetExponent >= -60); + DOUBLE_CONVERSION_ASSERT(kMaximalTargetExponent <= -32); // w is assumed to have an error less than 1 unit. Whenever w is scaled we // also scale its error. uint64_t w_error = 1; @@ -472,7 +472,7 @@ static bool DigitGenCounted(DiyFp w, // that is smaller than 'integrals'. while (*kappa > 0) { int digit = integrals / divisor; - ASSERT(digit <= 9); + DOUBLE_CONVERSION_ASSERT(digit <= 9); buffer[*length] = static_cast<char>('0' + digit); (*length)++; requested_digits--; @@ -498,15 +498,15 @@ static bool DigitGenCounted(DiyFp w, // data (the 'unit'), too. // Note that the multiplication by 10 does not overflow, because w.e >= -60 // and thus one.e >= -60. - ASSERT(one.e() >= -60); - ASSERT(fractionals < one.f()); - ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f()); + DOUBLE_CONVERSION_ASSERT(one.e() >= -60); + DOUBLE_CONVERSION_ASSERT(fractionals < one.f()); + DOUBLE_CONVERSION_ASSERT(DOUBLE_CONVERSION_UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f()); while (requested_digits > 0 && fractionals > w_error) { fractionals *= 10; w_error *= 10; // Integer division by one. int digit = static_cast<int>(fractionals >> -one.e()); - ASSERT(digit <= 9); + DOUBLE_CONVERSION_ASSERT(digit <= 9); buffer[*length] = static_cast<char>('0' + digit); (*length)++; requested_digits--; @@ -544,11 +544,11 @@ static bool Grisu3(double v, if (mode == FAST_DTOA_SHORTEST) { Double(v).NormalizedBoundaries(&boundary_minus, &boundary_plus); } else { - ASSERT(mode == FAST_DTOA_SHORTEST_SINGLE); + DOUBLE_CONVERSION_ASSERT(mode == FAST_DTOA_SHORTEST_SINGLE); float single_v = static_cast<float>(v); Single(single_v).NormalizedBoundaries(&boundary_minus, &boundary_plus); } - ASSERT(boundary_plus.e() == w.e()); + DOUBLE_CONVERSION_ASSERT(boundary_plus.e() == w.e()); DiyFp ten_mk; // Cached power of ten: 10^-k int mk; // -k int ten_mk_minimal_binary_exponent = @@ -559,7 +559,7 @@ static bool Grisu3(double v, ten_mk_minimal_binary_exponent, ten_mk_maximal_binary_exponent, &ten_mk, &mk); - ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() + + DOUBLE_CONVERSION_ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() + DiyFp::kSignificandSize) && (kMaximalTargetExponent >= w.e() + ten_mk.e() + DiyFp::kSignificandSize)); @@ -573,7 +573,7 @@ static bool Grisu3(double v, // In other words: let f = scaled_w.f() and e = scaled_w.e(), then // (f-1) * 2^e < w*10^k < (f+1) * 2^e DiyFp scaled_w = DiyFp::Times(w, ten_mk); - ASSERT(scaled_w.e() == + DOUBLE_CONVERSION_ASSERT(scaled_w.e() == boundary_plus.e() + ten_mk.e() + DiyFp::kSignificandSize); // In theory it would be possible to avoid some recomputations by computing // the difference between w and boundary_minus/plus (a power of 2) and to @@ -618,7 +618,7 @@ static bool Grisu3Counted(double v, ten_mk_minimal_binary_exponent, ten_mk_maximal_binary_exponent, &ten_mk, &mk); - ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() + + DOUBLE_CONVERSION_ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() + DiyFp::kSignificandSize) && (kMaximalTargetExponent >= w.e() + ten_mk.e() + DiyFp::kSignificandSize)); @@ -652,8 +652,8 @@ bool FastDtoa(double v, Vector<char> buffer, int* length, int* decimal_point) { - ASSERT(v > 0); - ASSERT(!Double(v).IsSpecial()); + DOUBLE_CONVERSION_ASSERT(v > 0); + DOUBLE_CONVERSION_ASSERT(!Double(v).IsSpecial()); bool result = false; int decimal_exponent = 0; @@ -667,7 +667,7 @@ bool FastDtoa(double v, buffer, length, &decimal_exponent); break; default: - UNREACHABLE(); + DOUBLE_CONVERSION_UNREACHABLE(); } if (result) { *decimal_point = *length + decimal_exponent; diff --git a/deps/icu-small/source/i18n/double-conversion-ieee.h b/deps/icu-small/source/i18n/double-conversion-ieee.h index c83c8d9abb..f4c62a9a9f 100644 --- a/deps/icu-small/source/i18n/double-conversion-ieee.h +++ b/deps/icu-small/source/i18n/double-conversion-ieee.h @@ -55,12 +55,14 @@ static float uint32_to_float(uint32_t d32) { return BitCast<float>(d32); } // Helper functions for doubles. class Double { public: - static const uint64_t kSignMask = UINT64_2PART_C(0x80000000, 00000000); - static const uint64_t kExponentMask = UINT64_2PART_C(0x7FF00000, 00000000); - static const uint64_t kSignificandMask = UINT64_2PART_C(0x000FFFFF, FFFFFFFF); - static const uint64_t kHiddenBit = UINT64_2PART_C(0x00100000, 00000000); + static const uint64_t kSignMask = DOUBLE_CONVERSION_UINT64_2PART_C(0x80000000, 00000000); + static const uint64_t kExponentMask = DOUBLE_CONVERSION_UINT64_2PART_C(0x7FF00000, 00000000); + static const uint64_t kSignificandMask = DOUBLE_CONVERSION_UINT64_2PART_C(0x000FFFFF, FFFFFFFF); + static const uint64_t kHiddenBit = DOUBLE_CONVERSION_UINT64_2PART_C(0x00100000, 00000000); static const int kPhysicalSignificandSize = 52; // Excludes the hidden bit. static const int kSignificandSize = 53; + static const int kExponentBias = 0x3FF + kPhysicalSignificandSize; + static const int kMaxExponent = 0x7FF - kExponentBias; Double() : d64_(0) {} explicit Double(double d) : d64_(double_to_uint64(d)) {} @@ -71,14 +73,14 @@ class Double { // The value encoded by this Double must be greater or equal to +0.0. // It must not be special (infinity, or NaN). DiyFp AsDiyFp() const { - ASSERT(Sign() > 0); - ASSERT(!IsSpecial()); + DOUBLE_CONVERSION_ASSERT(Sign() > 0); + DOUBLE_CONVERSION_ASSERT(!IsSpecial()); return DiyFp(Significand(), Exponent()); } // The value encoded by this Double must be strictly greater than 0. DiyFp AsNormalizedDiyFp() const { - ASSERT(value() > 0.0); + DOUBLE_CONVERSION_ASSERT(value() > 0.0); uint64_t f = Significand(); int e = Exponent(); @@ -174,7 +176,7 @@ class Double { // Precondition: the value encoded by this Double must be greater or equal // than +0.0. DiyFp UpperBoundary() const { - ASSERT(Sign() > 0); + DOUBLE_CONVERSION_ASSERT(Sign() > 0); return DiyFp(Significand() * 2 + 1, Exponent() - 1); } @@ -183,7 +185,7 @@ class Double { // exponent as m_plus. // Precondition: the value encoded by this Double must be greater than 0. void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const { - ASSERT(value() > 0.0); + DOUBLE_CONVERSION_ASSERT(value() > 0.0); DiyFp v = this->AsDiyFp(); DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1)); DiyFp m_minus; @@ -236,11 +238,9 @@ class Double { } private: - static const int kExponentBias = 0x3FF + kPhysicalSignificandSize; static const int kDenormalExponent = -kExponentBias + 1; - static const int kMaxExponent = 0x7FF - kExponentBias; - static const uint64_t kInfinity = UINT64_2PART_C(0x7FF00000, 00000000); - static const uint64_t kNaN = UINT64_2PART_C(0x7FF80000, 00000000); + static const uint64_t kInfinity = DOUBLE_CONVERSION_UINT64_2PART_C(0x7FF00000, 00000000); + static const uint64_t kNaN = DOUBLE_CONVERSION_UINT64_2PART_C(0x7FF80000, 00000000); const uint64_t d64_; @@ -271,7 +271,7 @@ class Double { (biased_exponent << kPhysicalSignificandSize); } - DC_DISALLOW_COPY_AND_ASSIGN(Double); + DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(Double); }; class Single { @@ -290,8 +290,8 @@ class Single { // The value encoded by this Single must be greater or equal to +0.0. // It must not be special (infinity, or NaN). DiyFp AsDiyFp() const { - ASSERT(Sign() > 0); - ASSERT(!IsSpecial()); + DOUBLE_CONVERSION_ASSERT(Sign() > 0); + DOUBLE_CONVERSION_ASSERT(!IsSpecial()); return DiyFp(Significand(), Exponent()); } @@ -354,7 +354,7 @@ class Single { // exponent as m_plus. // Precondition: the value encoded by this Single must be greater than 0. void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const { - ASSERT(value() > 0.0); + DOUBLE_CONVERSION_ASSERT(value() > 0.0); DiyFp v = this->AsDiyFp(); DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1)); DiyFp m_minus; @@ -372,7 +372,7 @@ class Single { // Precondition: the value encoded by this Single must be greater or equal // than +0.0. DiyFp UpperBoundary() const { - ASSERT(Sign() > 0); + DOUBLE_CONVERSION_ASSERT(Sign() > 0); return DiyFp(Significand() * 2 + 1, Exponent() - 1); } @@ -408,7 +408,7 @@ class Single { const uint32_t d32_; - DC_DISALLOW_COPY_AND_ASSIGN(Single); + DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(Single); }; } // namespace double_conversion diff --git a/deps/icu-small/source/i18n/double-conversion.cpp b/deps/icu-small/source/i18n/double-conversion-string-to-double.cpp index 1a60afbd64..946b2b26e7 100644 --- a/deps/icu-small/source/i18n/double-conversion.cpp +++ b/deps/icu-small/source/i18n/double-conversion-string-to-double.cpp @@ -37,16 +37,13 @@ // ICU PATCH: Do not include std::locale. #include <climits> -//#include <locale> +// #include <locale> #include <cmath> // ICU PATCH: Customize header file paths for ICU. -// The file fixed-dtoa.h is not needed. -#include "double-conversion.h" +#include "double-conversion-string-to-double.h" -#include "double-conversion-bignum-dtoa.h" -#include "double-conversion-fast-dtoa.h" #include "double-conversion-ieee.h" #include "double-conversion-strtod.h" #include "double-conversion-utils.h" @@ -56,385 +53,6 @@ U_NAMESPACE_BEGIN namespace double_conversion { -#if 0 // not needed for ICU -const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() { - int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN; - static DoubleToStringConverter converter(flags, - "Infinity", - "NaN", - 'e', - -6, 21, - 6, 0); - return converter; -} - - -bool DoubleToStringConverter::HandleSpecialValues( - double value, - StringBuilder* result_builder) const { - Double double_inspect(value); - if (double_inspect.IsInfinite()) { - if (infinity_symbol_ == NULL) return false; - if (value < 0) { - result_builder->AddCharacter('-'); - } - result_builder->AddString(infinity_symbol_); - return true; - } - if (double_inspect.IsNan()) { - if (nan_symbol_ == NULL) return false; - result_builder->AddString(nan_symbol_); - return true; - } - return false; -} - - -void DoubleToStringConverter::CreateExponentialRepresentation( - const char* decimal_digits, - int length, - int exponent, - StringBuilder* result_builder) const { - ASSERT(length != 0); - result_builder->AddCharacter(decimal_digits[0]); - if (length != 1) { - result_builder->AddCharacter('.'); - result_builder->AddSubstring(&decimal_digits[1], length-1); - } - result_builder->AddCharacter(exponent_character_); - if (exponent < 0) { - result_builder->AddCharacter('-'); - exponent = -exponent; - } else { - if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) { - result_builder->AddCharacter('+'); - } - } - if (exponent == 0) { - result_builder->AddCharacter('0'); - return; - } - ASSERT(exponent < 1e4); - const int kMaxExponentLength = 5; - char buffer[kMaxExponentLength + 1]; - buffer[kMaxExponentLength] = '\0'; - int first_char_pos = kMaxExponentLength; - while (exponent > 0) { - buffer[--first_char_pos] = '0' + (exponent % 10); - exponent /= 10; - } - result_builder->AddSubstring(&buffer[first_char_pos], - kMaxExponentLength - first_char_pos); -} - - -void DoubleToStringConverter::CreateDecimalRepresentation( - const char* decimal_digits, - int length, - int decimal_point, - int digits_after_point, - StringBuilder* result_builder) const { - // Create a representation that is padded with zeros if needed. - if (decimal_point <= 0) { - // "0.00000decimal_rep" or "0.000decimal_rep00". - result_builder->AddCharacter('0'); - if (digits_after_point > 0) { - result_builder->AddCharacter('.'); - result_builder->AddPadding('0', -decimal_point); - ASSERT(length <= digits_after_point - (-decimal_point)); - result_builder->AddSubstring(decimal_digits, length); - int remaining_digits = digits_after_point - (-decimal_point) - length; - result_builder->AddPadding('0', remaining_digits); - } - } else if (decimal_point >= length) { - // "decimal_rep0000.00000" or "decimal_rep.0000". - result_builder->AddSubstring(decimal_digits, length); - result_builder->AddPadding('0', decimal_point - length); - if (digits_after_point > 0) { - result_builder->AddCharacter('.'); - result_builder->AddPadding('0', digits_after_point); - } - } else { - // "decima.l_rep000". - ASSERT(digits_after_point > 0); - result_builder->AddSubstring(decimal_digits, decimal_point); - result_builder->AddCharacter('.'); - ASSERT(length - decimal_point <= digits_after_point); - result_builder->AddSubstring(&decimal_digits[decimal_point], - length - decimal_point); - int remaining_digits = digits_after_point - (length - decimal_point); - result_builder->AddPadding('0', remaining_digits); - } - if (digits_after_point == 0) { - if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) { - result_builder->AddCharacter('.'); - } - if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) { - result_builder->AddCharacter('0'); - } - } -} - - -bool DoubleToStringConverter::ToShortestIeeeNumber( - double value, - StringBuilder* result_builder, - DoubleToStringConverter::DtoaMode mode) const { - ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE); - if (Double(value).IsSpecial()) { - return HandleSpecialValues(value, result_builder); - } - - int decimal_point; - bool sign; - const int kDecimalRepCapacity = kBase10MaximalLength + 1; - char decimal_rep[kDecimalRepCapacity]; - int decimal_rep_length; - - DoubleToAscii(value, mode, 0, decimal_rep, kDecimalRepCapacity, - &sign, &decimal_rep_length, &decimal_point); - - bool unique_zero = (flags_ & UNIQUE_ZERO) != 0; - if (sign && (value != 0.0 || !unique_zero)) { - result_builder->AddCharacter('-'); - } - - int exponent = decimal_point - 1; - if ((decimal_in_shortest_low_ <= exponent) && - (exponent < decimal_in_shortest_high_)) { - CreateDecimalRepresentation(decimal_rep, decimal_rep_length, - decimal_point, - Max(0, decimal_rep_length - decimal_point), - result_builder); - } else { - CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent, - result_builder); - } - return true; -} - - -bool DoubleToStringConverter::ToFixed(double value, - int requested_digits, - StringBuilder* result_builder) const { - ASSERT(kMaxFixedDigitsBeforePoint == 60); - const double kFirstNonFixed = 1e60; - - if (Double(value).IsSpecial()) { - return HandleSpecialValues(value, result_builder); - } - - if (requested_digits > kMaxFixedDigitsAfterPoint) return false; - if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false; - - // Find a sufficiently precise decimal representation of n. - int decimal_point; - bool sign; - // Add space for the '\0' byte. - const int kDecimalRepCapacity = - kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1; - char decimal_rep[kDecimalRepCapacity]; - int decimal_rep_length; - DoubleToAscii(value, FIXED, requested_digits, - decimal_rep, kDecimalRepCapacity, - &sign, &decimal_rep_length, &decimal_point); - - bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); - if (sign && (value != 0.0 || !unique_zero)) { - result_builder->AddCharacter('-'); - } - - CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point, - requested_digits, result_builder); - return true; -} - - -bool DoubleToStringConverter::ToExponential( - double value, - int requested_digits, - StringBuilder* result_builder) const { - if (Double(value).IsSpecial()) { - return HandleSpecialValues(value, result_builder); - } - - if (requested_digits < -1) return false; - if (requested_digits > kMaxExponentialDigits) return false; - - int decimal_point; - bool sign; - // Add space for digit before the decimal point and the '\0' character. - const int kDecimalRepCapacity = kMaxExponentialDigits + 2; - ASSERT(kDecimalRepCapacity > kBase10MaximalLength); - char decimal_rep[kDecimalRepCapacity]; - int decimal_rep_length; - - if (requested_digits == -1) { - DoubleToAscii(value, SHORTEST, 0, - decimal_rep, kDecimalRepCapacity, - &sign, &decimal_rep_length, &decimal_point); - } else { - DoubleToAscii(value, PRECISION, requested_digits + 1, - decimal_rep, kDecimalRepCapacity, - &sign, &decimal_rep_length, &decimal_point); - ASSERT(decimal_rep_length <= requested_digits + 1); - - for (int i = decimal_rep_length; i < requested_digits + 1; ++i) { - decimal_rep[i] = '0'; - } - decimal_rep_length = requested_digits + 1; - } - - bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); - if (sign && (value != 0.0 || !unique_zero)) { - result_builder->AddCharacter('-'); - } - - int exponent = decimal_point - 1; - CreateExponentialRepresentation(decimal_rep, - decimal_rep_length, - exponent, - result_builder); - return true; -} - - -bool DoubleToStringConverter::ToPrecision(double value, - int precision, - StringBuilder* result_builder) const { - if (Double(value).IsSpecial()) { - return HandleSpecialValues(value, result_builder); - } - - if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) { - return false; - } - - // Find a sufficiently precise decimal representation of n. - int decimal_point; - bool sign; - // Add one for the terminating null character. - const int kDecimalRepCapacity = kMaxPrecisionDigits + 1; - char decimal_rep[kDecimalRepCapacity]; - int decimal_rep_length; - - DoubleToAscii(value, PRECISION, precision, - decimal_rep, kDecimalRepCapacity, - &sign, &decimal_rep_length, &decimal_point); - ASSERT(decimal_rep_length <= precision); - - bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); - if (sign && (value != 0.0 || !unique_zero)) { - result_builder->AddCharacter('-'); - } - - // The exponent if we print the number as x.xxeyyy. That is with the - // decimal point after the first digit. - int exponent = decimal_point - 1; - - int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0; - if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) || - (decimal_point - precision + extra_zero > - max_trailing_padding_zeroes_in_precision_mode_)) { - // Fill buffer to contain 'precision' digits. - // Usually the buffer is already at the correct length, but 'DoubleToAscii' - // is allowed to return less characters. - for (int i = decimal_rep_length; i < precision; ++i) { - decimal_rep[i] = '0'; - } - - CreateExponentialRepresentation(decimal_rep, - precision, - exponent, - result_builder); - } else { - CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point, - Max(0, precision - decimal_point), - result_builder); - } - return true; -} -#endif // not needed for ICU - - -static BignumDtoaMode DtoaToBignumDtoaMode( - DoubleToStringConverter::DtoaMode dtoa_mode) { - switch (dtoa_mode) { - case DoubleToStringConverter::SHORTEST: return BIGNUM_DTOA_SHORTEST; - case DoubleToStringConverter::SHORTEST_SINGLE: - return BIGNUM_DTOA_SHORTEST_SINGLE; - case DoubleToStringConverter::FIXED: return BIGNUM_DTOA_FIXED; - case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION; - default: - UNREACHABLE(); - } -} - - -void DoubleToStringConverter::DoubleToAscii(double v, - DtoaMode mode, - int requested_digits, - char* buffer, - int buffer_length, - bool* sign, - int* length, - int* point) { - Vector<char> vector(buffer, buffer_length); - ASSERT(!Double(v).IsSpecial()); - ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE || requested_digits >= 0); - - if (Double(v).Sign() < 0) { - *sign = true; - v = -v; - } else { - *sign = false; - } - - if (mode == PRECISION && requested_digits == 0) { - vector[0] = '\0'; - *length = 0; - return; - } - - if (v == 0) { - vector[0] = '0'; - vector[1] = '\0'; - *length = 1; - *point = 1; - return; - } - - bool fast_worked; - switch (mode) { - case SHORTEST: - fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point); - break; -#if 0 // not needed for ICU - case SHORTEST_SINGLE: - fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0, - vector, length, point); - break; - case FIXED: - fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point); - break; - case PRECISION: - fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits, - vector, length, point); - break; -#endif // not needed for ICU - default: - fast_worked = false; - UNREACHABLE(); - } - if (fast_worked) return; - - // If the fast dtoa didn't succeed use the slower bignum version. - BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode); - BignumDtoa(v, bignum_mode, requested_digits, vector, length, point); - vector[*length] = '\0'; -} - - namespace { inline char ToLower(char ch) { @@ -444,7 +62,7 @@ inline char ToLower(char ch) { return cType.tolower(ch); #else (void)ch; - UNREACHABLE(); + DOUBLE_CONVERSION_UNREACHABLE(); #endif } @@ -457,7 +75,7 @@ static inline bool ConsumeSubStringImpl(Iterator* current, Iterator end, const char* substring, Converter converter) { - ASSERT(converter(**current) == *substring); + DOUBLE_CONVERSION_ASSERT(converter(**current) == *substring); for (substring++; *substring != '\0'; substring++) { ++*current; if (*current == end || converter(**current) != *substring) { @@ -474,8 +92,8 @@ template <class Iterator> static bool ConsumeSubString(Iterator* current, Iterator end, const char* substring, - bool allow_case_insensibility) { - if (allow_case_insensibility) { + bool allow_case_insensitivity) { + if (allow_case_insensitivity) { return ConsumeSubStringImpl(current, end, substring, ToLower); } else { return ConsumeSubStringImpl(current, end, substring, Pass); @@ -485,8 +103,8 @@ static bool ConsumeSubString(Iterator* current, // Consumes first character of the str is equal to ch inline bool ConsumeFirstCharacter(char ch, const char* str, - bool case_insensibility) { - return case_insensibility ? ToLower(ch) == str[0] : ch == str[0]; + bool case_insensitivity) { + return case_insensitivity ? ToLower(ch) == str[0] : ch == str[0]; } } // namespace @@ -501,15 +119,14 @@ const int kMaxSignificantDigits = 772; static const char kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 }; -static const int kWhitespaceTable7Length = ARRAY_SIZE(kWhitespaceTable7); +static const int kWhitespaceTable7Length = DOUBLE_CONVERSION_ARRAY_SIZE(kWhitespaceTable7); static const uc16 kWhitespaceTable16[] = { 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279 }; -static const int kWhitespaceTable16Length = ARRAY_SIZE(kWhitespaceTable16); - +static const int kWhitespaceTable16Length = DOUBLE_CONVERSION_ARRAY_SIZE(kWhitespaceTable16); static bool isWhitespace(int x) { @@ -609,7 +226,7 @@ static bool IsHexFloatString(Iterator start, Iterator end, uc16 separator, bool allow_trailing_junk) { - ASSERT(start != end); + DOUBLE_CONVERSION_ASSERT(start != end); Iterator current = start; @@ -624,8 +241,8 @@ static bool IsHexFloatString(Iterator start, saw_digit = true; if (Advance(¤t, separator, 16, end)) return false; } - if (!saw_digit) return false; // Only the '.', but no digits. } + if (!saw_digit) return false; if (*current != 'p' && *current != 'P') return false; if (Advance(¤t, separator, 16, end)) return false; if (*current == '+' || *current == '-') { @@ -654,8 +271,8 @@ static double RadixStringToIeee(Iterator* current, double junk_string_value, bool read_as_double, bool* result_is_junk) { - ASSERT(*current != end); - ASSERT(!parse_as_hex_float || + DOUBLE_CONVERSION_ASSERT(*current != end); + DOUBLE_CONVERSION_ASSERT(!parse_as_hex_float || IsHexFloatString(*current, end, separator, allow_trailing_junk)); const int kDoubleSize = Double::kSignificandSize; @@ -693,7 +310,7 @@ static double RadixStringToIeee(Iterator* current, } else if (parse_as_hex_float && **current == '.') { post_decimal = true; Advance(current, separator, radix, end); - ASSERT(*current != end); + DOUBLE_CONVERSION_ASSERT(*current != end); continue; } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) { break; @@ -728,7 +345,7 @@ static double RadixStringToIeee(Iterator* current, // Just run over the '.'. We are just trying to see whether there is // a non-zero digit somewhere. Advance(current, separator, radix, end); - ASSERT(*current != end); + DOUBLE_CONVERSION_ASSERT(*current != end); post_decimal = true; } if (!isDigit(**current, radix)) break; @@ -763,27 +380,31 @@ static double RadixStringToIeee(Iterator* current, if (Advance(current, separator, radix, end)) break; } - ASSERT(number < ((int64_t)1 << kSignificandSize)); - ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); + DOUBLE_CONVERSION_ASSERT(number < ((int64_t)1 << kSignificandSize)); + DOUBLE_CONVERSION_ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); *result_is_junk = false; if (parse_as_hex_float) { - ASSERT(**current == 'p' || **current == 'P'); + DOUBLE_CONVERSION_ASSERT(**current == 'p' || **current == 'P'); Advance(current, separator, radix, end); - ASSERT(*current != end); + DOUBLE_CONVERSION_ASSERT(*current != end); bool is_negative = false; if (**current == '+') { Advance(current, separator, radix, end); - ASSERT(*current != end); + DOUBLE_CONVERSION_ASSERT(*current != end); } else if (**current == '-') { is_negative = true; Advance(current, separator, radix, end); - ASSERT(*current != end); + DOUBLE_CONVERSION_ASSERT(*current != end); } int written_exponent = 0; while (IsDecimalDigitForRadix(**current, 10)) { - written_exponent = 10 * written_exponent + **current - '0'; + // No need to read exponents if they are too big. That could potentially overflow + // the `written_exponent` variable. + if (abs(written_exponent) <= 100 * Double::kMaxExponent) { + written_exponent = 10 * written_exponent + **current - '0'; + } if (Advance(current, separator, radix, end)) break; } if (is_negative) written_exponent = -written_exponent; @@ -798,7 +419,7 @@ static double RadixStringToIeee(Iterator* current, return static_cast<double>(number); } - ASSERT(number != 0); + DOUBLE_CONVERSION_ASSERT(number != 0); double result = Double(DiyFp(number, exponent)).value(); return sign ? -result : result; } @@ -818,7 +439,7 @@ double StringToDoubleConverter::StringToIeee( const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0; const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0; const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0; - const bool allow_case_insensibility = (flags_ & ALLOW_CASE_INSENSIBILITY) != 0; + const bool allow_case_insensitivity = (flags_ & ALLOW_CASE_INSENSITIVITY) != 0; // To make sure that iterator dereferencing is valid the following // convention is used: @@ -868,8 +489,8 @@ double StringToDoubleConverter::StringToIeee( } if (infinity_symbol_ != NULL) { - if (ConsumeFirstCharacter(*current, infinity_symbol_, allow_case_insensibility)) { - if (!ConsumeSubString(¤t, end, infinity_symbol_, allow_case_insensibility)) { + if (ConsumeFirstCharacter(*current, infinity_symbol_, allow_case_insensitivity)) { + if (!ConsumeSubString(¤t, end, infinity_symbol_, allow_case_insensitivity)) { return junk_string_value_; } @@ -880,15 +501,15 @@ double StringToDoubleConverter::StringToIeee( return junk_string_value_; } - ASSERT(buffer_pos == 0); + DOUBLE_CONVERSION_ASSERT(buffer_pos == 0); *processed_characters_count = static_cast<int>(current - input); return sign ? -Double::Infinity() : Double::Infinity(); } } if (nan_symbol_ != NULL) { - if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensibility)) { - if (!ConsumeSubString(¤t, end, nan_symbol_, allow_case_insensibility)) { + if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensitivity)) { + if (!ConsumeSubString(¤t, end, nan_symbol_, allow_case_insensitivity)) { return junk_string_value_; } @@ -899,7 +520,7 @@ double StringToDoubleConverter::StringToIeee( return junk_string_value_; } - ASSERT(buffer_pos == 0); + DOUBLE_CONVERSION_ASSERT(buffer_pos == 0); *processed_characters_count = static_cast<int>(current - input); return sign ? -Double::NaN() : Double::NaN(); } @@ -919,10 +540,11 @@ double StringToDoubleConverter::StringToIeee( (*current == 'x' || *current == 'X')) { ++current; + if (current == end) return junk_string_value_; // "0x" + bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) && IsHexFloatString(current, end, separator_, allow_trailing_junk); - if (current == end) return junk_string_value_; // "0x" if (!parse_as_hex_float && !isDigit(*current, 16)) { return junk_string_value_; } @@ -958,7 +580,7 @@ double StringToDoubleConverter::StringToIeee( // Copy significant digits of the integer part (if any) to the buffer. while (*current >= '0' && *current <= '9') { if (significant_digits < kMaxSignificantDigits) { - ASSERT(buffer_pos < kBufferSize); + DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize); buffer[buffer_pos++] = static_cast<char>(*current); significant_digits++; // Will later check if it's an octal in the buffer. @@ -1003,7 +625,7 @@ double StringToDoubleConverter::StringToIeee( // We don't emit a '.', but adjust the exponent instead. while (*current >= '0' && *current <= '9') { if (significant_digits < kMaxSignificantDigits) { - ASSERT(buffer_pos < kBufferSize); + DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize); buffer[buffer_pos++] = static_cast<char>(*current); significant_digits++; exponent--; @@ -1061,7 +683,7 @@ double StringToDoubleConverter::StringToIeee( } const int max_exponent = INT_MAX / 2; - ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2); + DOUBLE_CONVERSION_ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2); int num = 0; do { // Check overflow. @@ -1104,7 +726,7 @@ double StringToDoubleConverter::StringToIeee( junk_string_value_, read_as_double, &result_is_junk); - ASSERT(!result_is_junk); + DOUBLE_CONVERSION_ASSERT(!result_is_junk); *processed_characters_count = static_cast<int>(current - input); return result; } @@ -1114,7 +736,7 @@ double StringToDoubleConverter::StringToIeee( exponent--; } - ASSERT(buffer_pos < kBufferSize); + DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize); buffer[buffer_pos] = '\0'; double converted; diff --git a/deps/icu-small/source/i18n/double-conversion-string-to-double.h b/deps/icu-small/source/i18n/double-conversion-string-to-double.h new file mode 100644 index 0000000000..2eb0c1f897 --- /dev/null +++ b/deps/icu-small/source/i18n/double-conversion-string-to-double.h @@ -0,0 +1,244 @@ +// © 2018 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +// +// From the double-conversion library. Original license: +// +// Copyright 2012 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// ICU PATCH: ifdef around UCONFIG_NO_FORMATTING +#include "unicode/utypes.h" +#if !UCONFIG_NO_FORMATTING + +#ifndef DOUBLE_CONVERSION_STRING_TO_DOUBLE_H_ +#define DOUBLE_CONVERSION_STRING_TO_DOUBLE_H_ + +// ICU PATCH: Customize header file paths for ICU. + +#include "double-conversion-utils.h" + +// ICU PATCH: Wrap in ICU namespace +U_NAMESPACE_BEGIN + +namespace double_conversion { + +class StringToDoubleConverter { + public: + // Enumeration for allowing octals and ignoring junk when converting + // strings to numbers. + enum Flags { + NO_FLAGS = 0, + ALLOW_HEX = 1, + ALLOW_OCTALS = 2, + ALLOW_TRAILING_JUNK = 4, + ALLOW_LEADING_SPACES = 8, + ALLOW_TRAILING_SPACES = 16, + ALLOW_SPACES_AFTER_SIGN = 32, + ALLOW_CASE_INSENSITIVITY = 64, + ALLOW_CASE_INSENSIBILITY = 64, // Deprecated + ALLOW_HEX_FLOATS = 128, + }; + + static const uc16 kNoSeparator = '\0'; + + // Flags should be a bit-or combination of the possible Flags-enum. + // - NO_FLAGS: no special flags. + // - ALLOW_HEX: recognizes the prefix "0x". Hex numbers may only be integers. + // Ex: StringToDouble("0x1234") -> 4660.0 + // In StringToDouble("0x1234.56") the characters ".56" are trailing + // junk. The result of the call is hence dependent on + // the ALLOW_TRAILING_JUNK flag and/or the junk value. + // With this flag "0x" is a junk-string. Even with ALLOW_TRAILING_JUNK, + // the string will not be parsed as "0" followed by junk. + // + // - ALLOW_OCTALS: recognizes the prefix "0" for octals: + // If a sequence of octal digits starts with '0', then the number is + // read as octal integer. Octal numbers may only be integers. + // Ex: StringToDouble("01234") -> 668.0 + // StringToDouble("012349") -> 12349.0 // Not a sequence of octal + // // digits. + // In StringToDouble("01234.56") the characters ".56" are trailing + // junk. The result of the call is hence dependent on + // the ALLOW_TRAILING_JUNK flag and/or the junk value. + // In StringToDouble("01234e56") the characters "e56" are trailing + // junk, too. + // - ALLOW_TRAILING_JUNK: ignore trailing characters that are not part of + // a double literal. + // - ALLOW_LEADING_SPACES: skip over leading whitespace, including spaces, + // new-lines, and tabs. + // - ALLOW_TRAILING_SPACES: ignore trailing whitespace. + // - ALLOW_SPACES_AFTER_SIGN: ignore whitespace after the sign. + // Ex: StringToDouble("- 123.2") -> -123.2. + // StringToDouble("+ 123.2") -> 123.2 + // - ALLOW_CASE_INSENSITIVITY: ignore case of characters for special values: + // infinity and nan. + // - ALLOW_HEX_FLOATS: allows hexadecimal float literals. + // This *must* start with "0x" and separate the exponent with "p". + // Examples: 0x1.2p3 == 9.0 + // 0x10.1p0 == 16.0625 + // ALLOW_HEX and ALLOW_HEX_FLOATS are indendent. + // + // empty_string_value is returned when an empty string is given as input. + // If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a string + // containing only spaces is converted to the 'empty_string_value', too. + // + // junk_string_value is returned when + // a) ALLOW_TRAILING_JUNK is not set, and a junk character (a character not + // part of a double-literal) is found. + // b) ALLOW_TRAILING_JUNK is set, but the string does not start with a + // double literal. + // + // infinity_symbol and nan_symbol are strings that are used to detect + // inputs that represent infinity and NaN. They can be null, in which case + // they are ignored. + // The conversion routine first reads any possible signs. Then it compares the + // following character of the input-string with the first character of + // the infinity, and nan-symbol. If either matches, the function assumes, that + // a match has been found, and expects the following input characters to match + // the remaining characters of the special-value symbol. + // This means that the following restrictions apply to special-value symbols: + // - they must not start with signs ('+', or '-'), + // - they must not have the same first character. + // - they must not start with digits. + // + // If the separator character is not kNoSeparator, then that specific + // character is ignored when in between two valid digits of the significant. + // It is not allowed to appear in the exponent. + // It is not allowed to lead or trail the number. + // It is not allowed to appear twice next to each other. + // + // Examples: + // flags = ALLOW_HEX | ALLOW_TRAILING_JUNK, + // empty_string_value = 0.0, + // junk_string_value = NaN, + // infinity_symbol = "infinity", + // nan_symbol = "nan": + // StringToDouble("0x1234") -> 4660.0. + // StringToDouble("0x1234K") -> 4660.0. + // StringToDouble("") -> 0.0 // empty_string_value. + // StringToDouble(" ") -> NaN // junk_string_value. + // StringToDouble(" 1") -> NaN // junk_string_value. + // StringToDouble("0x") -> NaN // junk_string_value. + // StringToDouble("-123.45") -> -123.45. + // StringToDouble("--123.45") -> NaN // junk_string_value. + // StringToDouble("123e45") -> 123e45. + // StringToDouble("123E45") -> 123e45. + // StringToDouble("123e+45") -> 123e45. + // StringToDouble("123E-45") -> 123e-45. + // StringToDouble("123e") -> 123.0 // trailing junk ignored. + // StringToDouble("123e-") -> 123.0 // trailing junk ignored. + // StringToDouble("+NaN") -> NaN // NaN string literal. + // StringToDouble("-infinity") -> -inf. // infinity literal. + // StringToDouble("Infinity") -> NaN // junk_string_value. + // + // flags = ALLOW_OCTAL | ALLOW_LEADING_SPACES, + // empty_string_value = 0.0, + // junk_string_value = NaN, + // infinity_symbol = NULL, + // nan_symbol = NULL: + // StringToDouble("0x1234") -> NaN // junk_string_value. + // StringToDouble("01234") -> 668.0. + // StringToDouble("") -> 0.0 // empty_string_value. + // StringToDouble(" ") -> 0.0 // empty_string_value. + // StringToDouble(" 1") -> 1.0 + // StringToDouble("0x") -> NaN // junk_string_value. + // StringToDouble("0123e45") -> NaN // junk_string_value. + // StringToDouble("01239E45") -> 1239e45. + // StringToDouble("-infinity") -> NaN // junk_string_value. + // StringToDouble("NaN") -> NaN // junk_string_value. + // + // flags = NO_FLAGS, + // separator = ' ': + // StringToDouble("1 2 3 4") -> 1234.0 + // StringToDouble("1 2") -> NaN // junk_string_value + // StringToDouble("1 000 000.0") -> 1000000.0 + // StringToDouble("1.000 000") -> 1.0 + // StringToDouble("1.0e1 000") -> NaN // junk_string_value + StringToDoubleConverter(int flags, + double empty_string_value, + double junk_string_value, + const char* infinity_symbol, + const char* nan_symbol, + uc16 separator = kNoSeparator) + : flags_(flags), + empty_string_value_(empty_string_value), + junk_string_value_(junk_string_value), + infinity_symbol_(infinity_symbol), + nan_symbol_(nan_symbol), + separator_(separator) { + } + + // Performs the conversion. + // The output parameter 'processed_characters_count' is set to the number + // of characters that have been processed to read the number. + // Spaces than are processed with ALLOW_{LEADING|TRAILING}_SPACES are included + // in the 'processed_characters_count'. Trailing junk is never included. + double StringToDouble(const char* buffer, + int length, + int* processed_characters_count) const; + + // Same as StringToDouble above but for 16 bit characters. + double StringToDouble(const uc16* buffer, + int length, + int* processed_characters_count) const; + + // Same as StringToDouble but reads a float. + // Note that this is not equivalent to static_cast<float>(StringToDouble(...)) + // due to potential double-rounding. + float StringToFloat(const char* buffer, + int length, + int* processed_characters_count) const; + + // Same as StringToFloat above but for 16 bit characters. + float StringToFloat(const uc16* buffer, + int length, + int* processed_characters_count) const; + + private: + const int flags_; + const double empty_string_value_; + const double junk_string_value_; + const char* const infinity_symbol_; + const char* const nan_symbol_; + const uc16 separator_; + + template <class Iterator> + double StringToIeee(Iterator start_pointer, + int length, + bool read_as_double, + int* processed_characters_count) const; + + DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter); +}; + +} // namespace double_conversion + +// ICU PATCH: Close ICU namespace +U_NAMESPACE_END + +#endif // DOUBLE_CONVERSION_STRING_TO_DOUBLE_H_ +#endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING diff --git a/deps/icu-small/source/i18n/double-conversion-strtod.cpp b/deps/icu-small/source/i18n/double-conversion-strtod.cpp index be9b0b3bce..9cf4854426 100644 --- a/deps/icu-small/source/i18n/double-conversion-strtod.cpp +++ b/deps/icu-small/source/i18n/double-conversion-strtod.cpp @@ -34,16 +34,15 @@ #include "unicode/utypes.h" #if !UCONFIG_NO_FORMATTING -#include <stdarg.h> -#include <limits.h> +#include <climits> +#include <cstdarg> // ICU PATCH: Customize header file paths for ICU. -// The file fixed-dtoa.h is not needed. -#include "double-conversion-strtod.h" #include "double-conversion-bignum.h" #include "double-conversion-cached-powers.h" #include "double-conversion-ieee.h" +#include "double-conversion-strtod.h" // ICU PATCH: Wrap in ICU namespace U_NAMESPACE_BEGIN @@ -67,7 +66,7 @@ static const int kMaxDecimalPower = 309; static const int kMinDecimalPower = -324; // 2^64 = 18446744073709551616 -static const uint64_t kMaxUint64 = UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF); +static const uint64_t kMaxUint64 = DOUBLE_CONVERSION_UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF); static const double exact_powers_of_ten[] = { @@ -96,7 +95,7 @@ static const double exact_powers_of_ten[] = { // 10^22 = 0x21e19e0c9bab2400000 = 0x878678326eac9 * 2^22 10000000000000000000000.0 }; -static const int kExactPowersOfTenSize = ARRAY_SIZE(exact_powers_of_ten); +static const int kExactPowersOfTenSize = DOUBLE_CONVERSION_ARRAY_SIZE(exact_powers_of_ten); // Maximum number of significant digits in the decimal representation. // In fact the value is 772 (see conversions.cc), but to give us some margin @@ -132,7 +131,7 @@ static void CutToMaxSignificantDigits(Vector<const char> buffer, } // The input buffer has been trimmed. Therefore the last digit must be // different from '0'. - ASSERT(buffer[buffer.length() - 1] != '0'); + DOUBLE_CONVERSION_ASSERT(buffer[buffer.length() - 1] != '0'); // Set the last digit to be non-zero. This is sufficient to guarantee // correct rounding. significant_buffer[kMaxSignificantDecimalDigits - 1] = '1'; @@ -153,7 +152,7 @@ static void TrimAndCut(Vector<const char> buffer, int exponent, exponent += left_trimmed.length() - right_trimmed.length(); if (right_trimmed.length() > kMaxSignificantDecimalDigits) { (void) space_size; // Mark variable as used. - ASSERT(space_size >= kMaxSignificantDecimalDigits); + DOUBLE_CONVERSION_ASSERT(space_size >= kMaxSignificantDecimalDigits); CutToMaxSignificantDigits(right_trimmed, exponent, buffer_copy_space, updated_exponent); *trimmed = Vector<const char>(buffer_copy_space, @@ -176,7 +175,7 @@ static uint64_t ReadUint64(Vector<const char> buffer, int i = 0; while (i < buffer.length() && result <= (kMaxUint64 / 10 - 1)) { int digit = buffer[i++] - '0'; - ASSERT(0 <= digit && digit <= 9); + DOUBLE_CONVERSION_ASSERT(0 <= digit && digit <= 9); result = 10 * result + digit; } *number_of_read_digits = i; @@ -220,7 +219,7 @@ static bool DoubleStrtod(Vector<const char> trimmed, // Note that the ARM simulator is compiled for 32bits. It therefore exhibits // the same problem. return false; -#endif +#else if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) { int read_digits; // The trimmed input fits into a double. @@ -232,14 +231,14 @@ static bool DoubleStrtod(Vector<const char> trimmed, if (exponent < 0 && -exponent < kExactPowersOfTenSize) { // 10^-exponent fits into a double. *result = static_cast<double>(ReadUint64(trimmed, &read_digits)); - ASSERT(read_digits == trimmed.length()); + DOUBLE_CONVERSION_ASSERT(read_digits == trimmed.length()); *result /= exact_powers_of_ten[-exponent]; return true; } if (0 <= exponent && exponent < kExactPowersOfTenSize) { // 10^exponent fits into a double. *result = static_cast<double>(ReadUint64(trimmed, &read_digits)); - ASSERT(read_digits == trimmed.length()); + DOUBLE_CONVERSION_ASSERT(read_digits == trimmed.length()); *result *= exact_powers_of_ten[exponent]; return true; } @@ -251,34 +250,35 @@ static bool DoubleStrtod(Vector<const char> trimmed, // 10^remaining_digits. As a result the remaining exponent now fits // into a double too. *result = static_cast<double>(ReadUint64(trimmed, &read_digits)); - ASSERT(read_digits == trimmed.length()); + DOUBLE_CONVERSION_ASSERT(read_digits == trimmed.length()); *result *= exact_powers_of_ten[remaining_digits]; *result *= exact_powers_of_ten[exponent - remaining_digits]; return true; } } return false; +#endif } // Returns 10^exponent as an exact DiyFp. // The given exponent must be in the range [1; kDecimalExponentDistance[. static DiyFp AdjustmentPowerOfTen(int exponent) { - ASSERT(0 < exponent); - ASSERT(exponent < PowersOfTenCache::kDecimalExponentDistance); + DOUBLE_CONVERSION_ASSERT(0 < exponent); + DOUBLE_CONVERSION_ASSERT(exponent < PowersOfTenCache::kDecimalExponentDistance); // Simply hardcode the remaining powers for the given decimal exponent // distance. - ASSERT(PowersOfTenCache::kDecimalExponentDistance == 8); + DOUBLE_CONVERSION_ASSERT(PowersOfTenCache::kDecimalExponentDistance == 8); switch (exponent) { - case 1: return DiyFp(UINT64_2PART_C(0xa0000000, 00000000), -60); - case 2: return DiyFp(UINT64_2PART_C(0xc8000000, 00000000), -57); - case 3: return DiyFp(UINT64_2PART_C(0xfa000000, 00000000), -54); - case 4: return DiyFp(UINT64_2PART_C(0x9c400000, 00000000), -50); - case 5: return DiyFp(UINT64_2PART_C(0xc3500000, 00000000), -47); - case 6: return DiyFp(UINT64_2PART_C(0xf4240000, 00000000), -44); - case 7: return DiyFp(UINT64_2PART_C(0x98968000, 00000000), -40); + case 1: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0xa0000000, 00000000), -60); + case 2: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0xc8000000, 00000000), -57); + case 3: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0xfa000000, 00000000), -54); + case 4: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0x9c400000, 00000000), -50); + case 5: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0xc3500000, 00000000), -47); + case 6: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0xf4240000, 00000000), -44); + case 7: return DiyFp(DOUBLE_CONVERSION_UINT64_2PART_C(0x98968000, 00000000), -40); default: - UNREACHABLE(); + DOUBLE_CONVERSION_UNREACHABLE(); } } @@ -307,7 +307,7 @@ static bool DiyFpStrtod(Vector<const char> buffer, input.Normalize(); error <<= old_e - input.e(); - ASSERT(exponent <= PowersOfTenCache::kMaxDecimalExponent); + DOUBLE_CONVERSION_ASSERT(exponent <= PowersOfTenCache::kMaxDecimalExponent); if (exponent < PowersOfTenCache::kMinDecimalExponent) { *result = 0.0; return true; @@ -325,7 +325,7 @@ static bool DiyFpStrtod(Vector<const char> buffer, if (kMaxUint64DecimalDigits - buffer.length() >= adjustment_exponent) { // The product of input with the adjustment power fits into a 64 bit // integer. - ASSERT(DiyFp::kSignificandSize == 64); + DOUBLE_CONVERSION_ASSERT(DiyFp::kSignificandSize == 64); } else { // The adjustment power is exact. There is hence only an error of 0.5. error += kDenominator / 2; @@ -367,8 +367,8 @@ static bool DiyFpStrtod(Vector<const char> buffer, precision_digits_count -= shift_amount; } // We use uint64_ts now. This only works if the DiyFp uses uint64_ts too. - ASSERT(DiyFp::kSignificandSize == 64); - ASSERT(precision_digits_count < 64); + DOUBLE_CONVERSION_ASSERT(DiyFp::kSignificandSize == 64); + DOUBLE_CONVERSION_ASSERT(precision_digits_count < 64); uint64_t one64 = 1; uint64_t precision_bits_mask = (one64 << precision_digits_count) - 1; uint64_t precision_bits = input.f() & precision_bits_mask; @@ -407,14 +407,14 @@ static bool DiyFpStrtod(Vector<const char> buffer, static int CompareBufferWithDiyFp(Vector<const char> buffer, int exponent, DiyFp diy_fp) { - ASSERT(buffer.length() + exponent <= kMaxDecimalPower + 1); - ASSERT(buffer.length() + exponent > kMinDecimalPower); - ASSERT(buffer.length() <= kMaxSignificantDecimalDigits); + DOUBLE_CONVERSION_ASSERT(buffer.length() + exponent <= kMaxDecimalPower + 1); + DOUBLE_CONVERSION_ASSERT(buffer.length() + exponent > kMinDecimalPower); + DOUBLE_CONVERSION_ASSERT(buffer.length() <= kMaxSignificantDecimalDigits); // Make sure that the Bignum will be able to hold all our numbers. // Our Bignum implementation has a separate field for exponents. Shifts will // consume at most one bigit (< 64 bits). // ln(10) == 3.3219... - ASSERT(((kMaxDecimalPower + 1) * 333 / 100) < Bignum::kMaxSignificantBits); + DOUBLE_CONVERSION_ASSERT(((kMaxDecimalPower + 1) * 333 / 100) < Bignum::kMaxSignificantBits); Bignum buffer_bignum; Bignum diy_fp_bignum; buffer_bignum.AssignDecimalString(buffer); @@ -460,18 +460,33 @@ static bool ComputeGuess(Vector<const char> trimmed, int exponent, return false; } -double Strtod(Vector<const char> buffer, int exponent) { - char copy_buffer[kMaxSignificantDecimalDigits]; - Vector<const char> trimmed; - int updated_exponent; - TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits, - &trimmed, &updated_exponent); - exponent = updated_exponent; +#if U_DEBUG // needed for ICU only in debug mode +static bool IsDigit(const char d) { + return ('0' <= d) && (d <= '9'); +} - double guess; - bool is_correct = ComputeGuess(trimmed, exponent, &guess); - if (is_correct) return guess; +static bool IsNonZeroDigit(const char d) { + return ('1' <= d) && (d <= '9'); +} + +static bool AssertTrimmedDigits(const Vector<const char>& buffer) { + for(int i = 0; i < buffer.length(); ++i) { + if(!IsDigit(buffer[i])) { + return false; + } + } + return (buffer.length() == 0) || (IsNonZeroDigit(buffer[0]) && IsNonZeroDigit(buffer[buffer.length()-1])); +} +#endif // needed for ICU only in debug mode +double StrtodTrimmed(Vector<const char> trimmed, int exponent) { + DOUBLE_CONVERSION_ASSERT(trimmed.length() <= kMaxSignificantDecimalDigits); + DOUBLE_CONVERSION_ASSERT(AssertTrimmedDigits(trimmed)); + double guess; + const bool is_correct = ComputeGuess(trimmed, exponent, &guess); + if (is_correct) { + return guess; + } DiyFp upper_boundary = Double(guess).UpperBoundary(); int comparison = CompareBufferWithDiyFp(trimmed, exponent, upper_boundary); if (comparison < 0) { @@ -486,6 +501,39 @@ double Strtod(Vector<const char> buffer, int exponent) { } } +double Strtod(Vector<const char> buffer, int exponent) { + char copy_buffer[kMaxSignificantDecimalDigits]; + Vector<const char> trimmed; + int updated_exponent; + TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits, + &trimmed, &updated_exponent); + return StrtodTrimmed(trimmed, updated_exponent); +} + +static float SanitizedDoubletof(double d) { + DOUBLE_CONVERSION_ASSERT(d >= 0.0); + // ASAN has a sanitize check that disallows casting doubles to floats if + // they are too big. + // https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#available-checks + // The behavior should be covered by IEEE 754, but some projects use this + // flag, so work around it. + float max_finite = 3.4028234663852885981170418348451692544e+38; + // The half-way point between the max-finite and infinity value. + // Since infinity has an even significand everything equal or greater than + // this value should become infinity. + double half_max_finite_infinity = + 3.40282356779733661637539395458142568448e+38; + if (d >= max_finite) { + if (d >= half_max_finite_infinity) { + return Single::Infinity(); + } else { + return max_finite; + } + } else { + return static_cast<float>(d); + } +} + float Strtof(Vector<const char> buffer, int exponent) { char copy_buffer[kMaxSignificantDecimalDigits]; Vector<const char> trimmed; @@ -497,7 +545,7 @@ float Strtof(Vector<const char> buffer, int exponent) { double double_guess; bool is_correct = ComputeGuess(trimmed, exponent, &double_guess); - float float_guess = static_cast<float>(double_guess); + float float_guess = SanitizedDoubletof(double_guess); if (float_guess == double_guess) { // This shortcut triggers for integer values. return float_guess; @@ -520,18 +568,18 @@ float Strtof(Vector<const char> buffer, int exponent) { double double_next = Double(double_guess).NextDouble(); double double_previous = Double(double_guess).PreviousDouble(); - float f1 = static_cast<float>(double_previous); + float f1 = SanitizedDoubletof(double_previous); float f2 = float_guess; - float f3 = static_cast<float>(double_next); + float f3 = SanitizedDoubletof(double_next); float f4; if (is_correct) { f4 = f3; } else { double double_next2 = Double(double_next).NextDouble(); - f4 = static_cast<float>(double_next2); + f4 = SanitizedDoubletof(double_next2); } (void) f2; // Mark variable as used. - ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4); + DOUBLE_CONVERSION_ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4); // If the guess doesn't lie near a single-precision boundary we can simply // return its float-value. @@ -539,11 +587,11 @@ float Strtof(Vector<const char> buffer, int exponent) { return float_guess; } - ASSERT((f1 != f2 && f2 == f3 && f3 == f4) || + DOUBLE_CONVERSION_ASSERT((f1 != f2 && f2 == f3 && f3 == f4) || (f1 == f2 && f2 != f3 && f3 == f4) || (f1 == f2 && f2 == f3 && f3 != f4)); - // guess and next are the two possible canditates (in the same way that + // guess and next are the two possible candidates (in the same way that // double_guess was the lower candidate for a double-precision guess). float guess = f1; float next = f4; diff --git a/deps/icu-small/source/i18n/double-conversion-strtod.h b/deps/icu-small/source/i18n/double-conversion-strtod.h index e2d6d3c2fe..50ef746401 100644 --- a/deps/icu-small/source/i18n/double-conversion-strtod.h +++ b/deps/icu-small/source/i18n/double-conversion-strtod.h @@ -54,6 +54,11 @@ double Strtod(Vector<const char> buffer, int exponent); // contain a dot or a sign. It must not start with '0', and must not be empty. float Strtof(Vector<const char> buffer, int exponent); +// For special use cases, the heart of the Strtod() function is also available +// separately, it assumes that 'trimmed' is as produced by TrimAndCut(), i.e. +// no leading or trailing zeros, also no lone zero, and not 'too many' digits. +double StrtodTrimmed(Vector<const char> trimmed, int exponent); + } // namespace double_conversion // ICU PATCH: Close ICU namespace diff --git a/deps/icu-small/source/i18n/double-conversion-utils.h b/deps/icu-small/source/i18n/double-conversion-utils.h index 1e44fcaa0e..099298460c 100644 --- a/deps/icu-small/source/i18n/double-conversion-utils.h +++ b/deps/icu-small/source/i18n/double-conversion-utils.h @@ -42,10 +42,12 @@ // ICU PATCH: Use U_ASSERT instead of <assert.h> #include "uassert.h" -#define ASSERT U_ASSERT - -#ifndef UNIMPLEMENTED -#define UNIMPLEMENTED() (abort()) +#ifndef DOUBLE_CONVERSION_ASSERT +#define DOUBLE_CONVERSION_ASSERT(condition) \ + U_ASSERT(condition); +#endif +#ifndef DOUBLE_CONVERSION_UNIMPLEMENTED +#define DOUBLE_CONVERSION_UNIMPLEMENTED() (abort()) #endif #ifndef DOUBLE_CONVERSION_NO_RETURN #ifdef _MSC_VER @@ -54,16 +56,23 @@ #define DOUBLE_CONVERSION_NO_RETURN __attribute__((noreturn)) #endif #endif -#ifndef UNREACHABLE +#ifndef DOUBLE_CONVERSION_UNREACHABLE #ifdef _MSC_VER void DOUBLE_CONVERSION_NO_RETURN abort_noreturn(); inline void abort_noreturn() { abort(); } -#define UNREACHABLE() (abort_noreturn()) +#define DOUBLE_CONVERSION_UNREACHABLE() (abort_noreturn()) #else -#define UNREACHABLE() (abort()) +#define DOUBLE_CONVERSION_UNREACHABLE() (abort()) #endif #endif +#ifndef DOUBLE_CONVERSION_UNUSED +#ifdef __GNUC__ +#define DOUBLE_CONVERSION_UNUSED __attribute__((unused)) +#else +#define DOUBLE_CONVERSION_UNUSED +#endif +#endif // Double operations detection based on target architecture. // Linux uses a 80bit wide floating point stack on x86. This induces double @@ -99,9 +108,9 @@ int main(int argc, char** argv) { defined(_POWER) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \ defined(__sparc__) || defined(__sparc) || defined(__s390__) || \ defined(__SH4__) || defined(__alpha__) || \ - defined(_MIPS_ARCH_MIPS32R2) || \ + defined(_MIPS_ARCH_MIPS32R2) || defined(__ARMEB__) ||\ defined(__AARCH64EL__) || defined(__aarch64__) || defined(__AARCH64EB__) || \ - defined(__riscv) || \ + defined(__riscv) || defined(__e2k__) || \ defined(__or1k__) || defined(__arc__) || \ defined(__EMSCRIPTEN__) #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 @@ -141,24 +150,24 @@ typedef uint16_t uc16; // The following macro works on both 32 and 64-bit platforms. // Usage: instead of writing 0x1234567890123456 -// write UINT64_2PART_C(0x12345678,90123456); -#define UINT64_2PART_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u)) +// write DOUBLE_CONVERSION_UINT64_2PART_C(0x12345678,90123456); +#define DOUBLE_CONVERSION_UINT64_2PART_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u)) -// The expression ARRAY_SIZE(a) is a compile-time constant of type +// The expression DOUBLE_CONVERSION_ARRAY_SIZE(a) is a compile-time constant of type // size_t which represents the number of elements of the given -// array. You should only use ARRAY_SIZE on statically allocated +// array. You should only use DOUBLE_CONVERSION_ARRAY_SIZE on statically allocated // arrays. -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) \ +#ifndef DOUBLE_CONVERSION_ARRAY_SIZE +#define DOUBLE_CONVERSION_ARRAY_SIZE(a) \ ((sizeof(a) / sizeof(*(a))) / \ static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) #endif // A macro to disallow the evil copy constructor and operator= functions // This should be used in the private: declarations for a class -#ifndef DC_DISALLOW_COPY_AND_ASSIGN -#define DC_DISALLOW_COPY_AND_ASSIGN(TypeName) \ +#ifndef DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN +#define DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&); \ void operator=(const TypeName&) #endif @@ -169,10 +178,10 @@ typedef uint16_t uc16; // This should be used in the private: declarations for a class // that wants to prevent anyone from instantiating it. This is // especially useful for classes containing only static methods. -#ifndef DC_DISALLOW_IMPLICIT_CONSTRUCTORS -#define DC_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ +#ifndef DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS +#define DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ TypeName(); \ - DC_DISALLOW_COPY_AND_ASSIGN(TypeName) + DOUBLE_CONVERSION_DISALLOW_COPY_AND_ASSIGN(TypeName) #endif // ICU PATCH: Wrap in ICU namespace @@ -180,25 +189,9 @@ U_NAMESPACE_BEGIN namespace double_conversion { -static const int kCharSize = sizeof(char); - -// Returns the maximum of the two parameters. -template <typename T> -static T Max(T a, T b) { - return a < b ? b : a; -} - - -// Returns the minimum of the two parameters. -template <typename T> -static T Min(T a, T b) { - return a < b ? a : b; -} - - inline int StrLength(const char* string) { size_t length = strlen(string); - ASSERT(length == static_cast<size_t>(static_cast<int>(length))); + DOUBLE_CONVERSION_ASSERT(length == static_cast<size_t>(static_cast<int>(length))); return static_cast<int>(length); } @@ -208,15 +201,15 @@ class Vector { public: Vector() : start_(NULL), length_(0) {} Vector(T* data, int len) : start_(data), length_(len) { - ASSERT(len == 0 || (len > 0 && data != NULL)); + DOUBLE_CONVERSION_ASSERT(len == 0 || (len > 0 && data != NULL)); } // Returns a vector using the same backing storage as this one, // spanning from and including 'from', to but not including 'to'. Vector<T> SubVector(int from, int to) { - ASSERT(to <= length_); - ASSERT(from < to); - ASSERT(0 <= from); + DOUBLE_CONVERSION_ASSERT(to <= length_); + DOUBLE_CONVERSION_ASSERT(from < to); + DOUBLE_CONVERSION_ASSERT(0 <= from); return Vector<T>(start() + from, to - from); } @@ -231,7 +224,7 @@ class Vector { // Access individual vector elements - checks bounds in debug mode. T& operator[](int index) const { - ASSERT(0 <= index && index < length_); + DOUBLE_CONVERSION_ASSERT(0 <= index && index < length_); return start_[index]; } @@ -239,6 +232,11 @@ class Vector { T& last() { return start_[length_ - 1]; } + void pop_back() { + DOUBLE_CONVERSION_ASSERT(!is_empty()); + --length_; + } + private: T* start_; int length_; @@ -259,7 +257,7 @@ class StringBuilder { // Get the current position in the builder. int position() const { - ASSERT(!is_finalized()); + DOUBLE_CONVERSION_ASSERT(!is_finalized()); return position_; } @@ -270,8 +268,8 @@ class StringBuilder { // 0-characters; use the Finalize() method to terminate the string // instead. void AddCharacter(char c) { - ASSERT(c != '\0'); - ASSERT(!is_finalized() && position_ < buffer_.length()); + DOUBLE_CONVERSION_ASSERT(c != '\0'); + DOUBLE_CONVERSION_ASSERT(!is_finalized() && position_ < buffer_.length()); buffer_[position_++] = c; } @@ -284,9 +282,9 @@ class StringBuilder { // Add the first 'n' characters of the given string 's' to the // builder. The input string must have enough characters. void AddSubstring(const char* s, int n) { - ASSERT(!is_finalized() && position_ + n < buffer_.length()); - ASSERT(static_cast<size_t>(n) <= strlen(s)); - memmove(&buffer_[position_], s, n * kCharSize); + DOUBLE_CONVERSION_ASSERT(!is_finalized() && position_ + n < buffer_.length()); + DOUBLE_CONVERSION_ASSERT(static_cast<size_t>(n) <= strlen(s)); + memmove(&buffer_[position_], s, n); position_ += n; } @@ -301,13 +299,13 @@ class StringBuilder { // Finalize the string by 0-terminating it and returning the buffer. char* Finalize() { - ASSERT(!is_finalized() && position_ < buffer_.length()); + DOUBLE_CONVERSION_ASSERT(!is_finalized() && position_ < buffer_.length()); buffer_[position_] = '\0'; // Make sure nobody managed to add a 0-character to the // buffer while building the string. - ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_)); + DOUBLE_CONVERSION_ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_)); position_ = -1; - ASSERT(is_finalized()); + DOUBLE_CONVERSION_ASSERT(is_finalized()); return buffer_.start(); } @@ -317,7 +315,7 @@ class StringBuilder { bool is_finalized() const { return position_ < 0; } - DC_DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder); + DOUBLE_CONVERSION_DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder); }; // The type-based aliasing rule allows the compiler to assume that pointers of @@ -345,13 +343,14 @@ class StringBuilder { // enough that it can no longer see that you have cast one pointer type to // another thus avoiding the warning. template <class Dest, class Source> -inline Dest BitCast(const Source& source) { +Dest BitCast(const Source& source) { // Compile time assertion: sizeof(Dest) == sizeof(Source) // A compile error here means your Dest and Source have different sizes. #if __cplusplus >= 201103L static_assert(sizeof(Dest) == sizeof(Source), "source and destination size mismatch"); #else + DOUBLE_CONVERSION_UNUSED typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1]; #endif @@ -361,7 +360,7 @@ inline Dest BitCast(const Source& source) { } template <class Dest, class Source> -inline Dest BitCast(Source* source) { +Dest BitCast(Source* source) { return BitCast<Dest>(reinterpret_cast<uintptr_t>(source)); } diff --git a/deps/icu-small/source/i18n/double-conversion.h b/deps/icu-small/source/i18n/double-conversion.h index 377c710bf7..eddc38763b 100644 --- a/deps/icu-small/source/i18n/double-conversion.h +++ b/deps/icu-small/source/i18n/double-conversion.h @@ -39,561 +39,8 @@ // ICU PATCH: Customize header file paths for ICU. -#include "double-conversion-utils.h" - -// ICU PATCH: Wrap in ICU namespace -U_NAMESPACE_BEGIN - -namespace double_conversion { - -class DoubleToStringConverter { - public: -#if 0 // not needed for ICU - // When calling ToFixed with a double > 10^kMaxFixedDigitsBeforePoint - // or a requested_digits parameter > kMaxFixedDigitsAfterPoint then the - // function returns false. - static const int kMaxFixedDigitsBeforePoint = 60; - static const int kMaxFixedDigitsAfterPoint = 60; - - // When calling ToExponential with a requested_digits - // parameter > kMaxExponentialDigits then the function returns false. - static const int kMaxExponentialDigits = 120; - - // When calling ToPrecision with a requested_digits - // parameter < kMinPrecisionDigits or requested_digits > kMaxPrecisionDigits - // then the function returns false. - static const int kMinPrecisionDigits = 1; - static const int kMaxPrecisionDigits = 120; - - enum Flags { - NO_FLAGS = 0, - EMIT_POSITIVE_EXPONENT_SIGN = 1, - EMIT_TRAILING_DECIMAL_POINT = 2, - EMIT_TRAILING_ZERO_AFTER_POINT = 4, - UNIQUE_ZERO = 8 - }; - - // Flags should be a bit-or combination of the possible Flags-enum. - // - NO_FLAGS: no special flags. - // - EMIT_POSITIVE_EXPONENT_SIGN: when the number is converted into exponent - // form, emits a '+' for positive exponents. Example: 1.2e+2. - // - EMIT_TRAILING_DECIMAL_POINT: when the input number is an integer and is - // converted into decimal format then a trailing decimal point is appended. - // Example: 2345.0 is converted to "2345.". - // - EMIT_TRAILING_ZERO_AFTER_POINT: in addition to a trailing decimal point - // emits a trailing '0'-character. This flag requires the - // EXMIT_TRAILING_DECIMAL_POINT flag. - // Example: 2345.0 is converted to "2345.0". - // - UNIQUE_ZERO: "-0.0" is converted to "0.0". - // - // Infinity symbol and nan_symbol provide the string representation for these - // special values. If the string is NULL and the special value is encountered - // then the conversion functions return false. - // - // The exponent_character is used in exponential representations. It is - // usually 'e' or 'E'. - // - // When converting to the shortest representation the converter will - // represent input numbers in decimal format if they are in the interval - // [10^decimal_in_shortest_low; 10^decimal_in_shortest_high[ - // (lower boundary included, greater boundary excluded). - // Example: with decimal_in_shortest_low = -6 and - // decimal_in_shortest_high = 21: - // ToShortest(0.000001) -> "0.000001" - // ToShortest(0.0000001) -> "1e-7" - // ToShortest(111111111111111111111.0) -> "111111111111111110000" - // ToShortest(100000000000000000000.0) -> "100000000000000000000" - // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21" - // - // When converting to precision mode the converter may add - // max_leading_padding_zeroes before returning the number in exponential - // format. - // Example with max_leading_padding_zeroes_in_precision_mode = 6. - // ToPrecision(0.0000012345, 2) -> "0.0000012" - // ToPrecision(0.00000012345, 2) -> "1.2e-7" - // Similarily the converter may add up to - // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid - // returning an exponential representation. A zero added by the - // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit. - // Examples for max_trailing_padding_zeroes_in_precision_mode = 1: - // ToPrecision(230.0, 2) -> "230" - // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT. - // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT. - DoubleToStringConverter(int flags, - const char* infinity_symbol, - const char* nan_symbol, - char exponent_character, - int decimal_in_shortest_low, - int decimal_in_shortest_high, - int max_leading_padding_zeroes_in_precision_mode, - int max_trailing_padding_zeroes_in_precision_mode) - : flags_(flags), - infinity_symbol_(infinity_symbol), - nan_symbol_(nan_symbol), - exponent_character_(exponent_character), - decimal_in_shortest_low_(decimal_in_shortest_low), - decimal_in_shortest_high_(decimal_in_shortest_high), - max_leading_padding_zeroes_in_precision_mode_( - max_leading_padding_zeroes_in_precision_mode), - max_trailing_padding_zeroes_in_precision_mode_( - max_trailing_padding_zeroes_in_precision_mode) { - // When 'trailing zero after the point' is set, then 'trailing point' - // must be set too. - ASSERT(((flags & EMIT_TRAILING_DECIMAL_POINT) != 0) || - !((flags & EMIT_TRAILING_ZERO_AFTER_POINT) != 0)); - } - - // Returns a converter following the EcmaScript specification. - static const DoubleToStringConverter& EcmaScriptConverter(); - - // Computes the shortest string of digits that correctly represent the input - // number. Depending on decimal_in_shortest_low and decimal_in_shortest_high - // (see constructor) it then either returns a decimal representation, or an - // exponential representation. - // Example with decimal_in_shortest_low = -6, - // decimal_in_shortest_high = 21, - // EMIT_POSITIVE_EXPONENT_SIGN activated, and - // EMIT_TRAILING_DECIMAL_POINT deactived: - // ToShortest(0.000001) -> "0.000001" - // ToShortest(0.0000001) -> "1e-7" - // ToShortest(111111111111111111111.0) -> "111111111111111110000" - // ToShortest(100000000000000000000.0) -> "100000000000000000000" - // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21" - // - // Note: the conversion may round the output if the returned string - // is accurate enough to uniquely identify the input-number. - // For example the most precise representation of the double 9e59 equals - // "899999999999999918767229449717619953810131273674690656206848", but - // the converter will return the shorter (but still correct) "9e59". - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except when the input value is special and no infinity_symbol or - // nan_symbol has been given to the constructor. - bool ToShortest(double value, StringBuilder* result_builder) const { - return ToShortestIeeeNumber(value, result_builder, SHORTEST); - } - - // Same as ToShortest, but for single-precision floats. - bool ToShortestSingle(float value, StringBuilder* result_builder) const { - return ToShortestIeeeNumber(value, result_builder, SHORTEST_SINGLE); - } - - - // Computes a decimal representation with a fixed number of digits after the - // decimal point. The last emitted digit is rounded. - // - // Examples: - // ToFixed(3.12, 1) -> "3.1" - // ToFixed(3.1415, 3) -> "3.142" - // ToFixed(1234.56789, 4) -> "1234.5679" - // ToFixed(1.23, 5) -> "1.23000" - // ToFixed(0.1, 4) -> "0.1000" - // ToFixed(1e30, 2) -> "1000000000000000019884624838656.00" - // ToFixed(0.1, 30) -> "0.100000000000000005551115123126" - // ToFixed(0.1, 17) -> "0.10000000000000001" - // - // If requested_digits equals 0, then the tail of the result depends on - // the EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT. - // Examples, for requested_digits == 0, - // let EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT be - // - false and false: then 123.45 -> 123 - // 0.678 -> 1 - // - true and false: then 123.45 -> 123. - // 0.678 -> 1. - // - true and true: then 123.45 -> 123.0 - // 0.678 -> 1.0 - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except for the following cases: - // - the input value is special and no infinity_symbol or nan_symbol has - // been provided to the constructor, - // - 'value' > 10^kMaxFixedDigitsBeforePoint, or - // - 'requested_digits' > kMaxFixedDigitsAfterPoint. - // The last two conditions imply that the result will never contain more than - // 1 + kMaxFixedDigitsBeforePoint + 1 + kMaxFixedDigitsAfterPoint characters - // (one additional character for the sign, and one for the decimal point). - bool ToFixed(double value, - int requested_digits, - StringBuilder* result_builder) const; - - // Computes a representation in exponential format with requested_digits - // after the decimal point. The last emitted digit is rounded. - // If requested_digits equals -1, then the shortest exponential representation - // is computed. - // - // Examples with EMIT_POSITIVE_EXPONENT_SIGN deactivated, and - // exponent_character set to 'e'. - // ToExponential(3.12, 1) -> "3.1e0" - // ToExponential(5.0, 3) -> "5.000e0" - // ToExponential(0.001, 2) -> "1.00e-3" - // ToExponential(3.1415, -1) -> "3.1415e0" - // ToExponential(3.1415, 4) -> "3.1415e0" - // ToExponential(3.1415, 3) -> "3.142e0" - // ToExponential(123456789000000, 3) -> "1.235e14" - // ToExponential(1000000000000000019884624838656.0, -1) -> "1e30" - // ToExponential(1000000000000000019884624838656.0, 32) -> - // "1.00000000000000001988462483865600e30" - // ToExponential(1234, 0) -> "1e3" - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except for the following cases: - // - the input value is special and no infinity_symbol or nan_symbol has - // been provided to the constructor, - // - 'requested_digits' > kMaxExponentialDigits. - // The last condition implies that the result will never contain more than - // kMaxExponentialDigits + 8 characters (the sign, the digit before the - // decimal point, the decimal point, the exponent character, the - // exponent's sign, and at most 3 exponent digits). - bool ToExponential(double value, - int requested_digits, - StringBuilder* result_builder) const; - - // Computes 'precision' leading digits of the given 'value' and returns them - // either in exponential or decimal format, depending on - // max_{leading|trailing}_padding_zeroes_in_precision_mode (given to the - // constructor). - // The last computed digit is rounded. - // - // Example with max_leading_padding_zeroes_in_precision_mode = 6. - // ToPrecision(0.0000012345, 2) -> "0.0000012" - // ToPrecision(0.00000012345, 2) -> "1.2e-7" - // Similarily the converter may add up to - // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid - // returning an exponential representation. A zero added by the - // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit. - // Examples for max_trailing_padding_zeroes_in_precision_mode = 1: - // ToPrecision(230.0, 2) -> "230" - // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT. - // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT. - // Examples for max_trailing_padding_zeroes_in_precision_mode = 3, and no - // EMIT_TRAILING_ZERO_AFTER_POINT: - // ToPrecision(123450.0, 6) -> "123450" - // ToPrecision(123450.0, 5) -> "123450" - // ToPrecision(123450.0, 4) -> "123500" - // ToPrecision(123450.0, 3) -> "123000" - // ToPrecision(123450.0, 2) -> "1.2e5" - // - // Returns true if the conversion succeeds. The conversion always succeeds - // except for the following cases: - // - the input value is special and no infinity_symbol or nan_symbol has - // been provided to the constructor, - // - precision < kMinPericisionDigits - // - precision > kMaxPrecisionDigits - // The last condition implies that the result will never contain more than - // kMaxPrecisionDigits + 7 characters (the sign, the decimal point, the - // exponent character, the exponent's sign, and at most 3 exponent digits). - bool ToPrecision(double value, - int precision, - StringBuilder* result_builder) const; -#endif // not needed for ICU - - enum DtoaMode { - // Produce the shortest correct representation. - // For example the output of 0.299999999999999988897 is (the less accurate - // but correct) 0.3. - SHORTEST, - // Same as SHORTEST, but for single-precision floats. - SHORTEST_SINGLE, - // Produce a fixed number of digits after the decimal point. - // For instance fixed(0.1, 4) becomes 0.1000 - // If the input number is big, the output will be big. - FIXED, - // Fixed number of digits (independent of the decimal point). - PRECISION - }; - - // The maximal number of digits that are needed to emit a double in base 10. - // A higher precision can be achieved by using more digits, but the shortest - // accurate representation of any double will never use more digits than - // kBase10MaximalLength. - // Note that DoubleToAscii null-terminates its input. So the given buffer - // should be at least kBase10MaximalLength + 1 characters long. - static const int kBase10MaximalLength = 17; - - // Converts the given double 'v' to digit characters. 'v' must not be NaN, - // +Infinity, or -Infinity. In SHORTEST_SINGLE-mode this restriction also - // applies to 'v' after it has been casted to a single-precision float. That - // is, in this mode static_cast<float>(v) must not be NaN, +Infinity or - // -Infinity. - // - // The result should be interpreted as buffer * 10^(point-length). - // - // The digits are written to the buffer in the platform's charset, which is - // often UTF-8 (with ASCII-range digits) but may be another charset, such - // as EBCDIC. - // - // The output depends on the given mode: - // - SHORTEST: produce the least amount of digits for which the internal - // identity requirement is still satisfied. If the digits are printed - // (together with the correct exponent) then reading this number will give - // 'v' again. The buffer will choose the representation that is closest to - // 'v'. If there are two at the same distance, than the one farther away - // from 0 is chosen (halfway cases - ending with 5 - are rounded up). - // In this mode the 'requested_digits' parameter is ignored. - // - SHORTEST_SINGLE: same as SHORTEST but with single-precision. - // - FIXED: produces digits necessary to print a given number with - // 'requested_digits' digits after the decimal point. The produced digits - // might be too short in which case the caller has to fill the remainder - // with '0's. - // Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2. - // Halfway cases are rounded towards +/-Infinity (away from 0). The call - // toFixed(0.15, 2) thus returns buffer="2", point=0. - // The returned buffer may contain digits that would be truncated from the - // shortest representation of the input. - // - PRECISION: produces 'requested_digits' where the first digit is not '0'. - // Even though the length of produced digits usually equals - // 'requested_digits', the function is allowed to return fewer digits, in - // which case the caller has to fill the missing digits with '0's. - // Halfway cases are again rounded away from 0. - // DoubleToAscii expects the given buffer to be big enough to hold all - // digits and a terminating null-character. In SHORTEST-mode it expects a - // buffer of at least kBase10MaximalLength + 1. In all other modes the - // requested_digits parameter and the padding-zeroes limit the size of the - // output. Don't forget the decimal point, the exponent character and the - // terminating null-character when computing the maximal output size. - // The given length is only used in debug mode to ensure the buffer is big - // enough. - // ICU PATCH: Export this as U_I18N_API for unit tests. - static void U_I18N_API DoubleToAscii(double v, - DtoaMode mode, - int requested_digits, - char* buffer, - int buffer_length, - bool* sign, - int* length, - int* point); - -#if 0 // not needed for ICU - private: - // Implementation for ToShortest and ToShortestSingle. - bool ToShortestIeeeNumber(double value, - StringBuilder* result_builder, - DtoaMode mode) const; - - // If the value is a special value (NaN or Infinity) constructs the - // corresponding string using the configured infinity/nan-symbol. - // If either of them is NULL or the value is not special then the - // function returns false. - bool HandleSpecialValues(double value, StringBuilder* result_builder) const; - // Constructs an exponential representation (i.e. 1.234e56). - // The given exponent assumes a decimal point after the first decimal digit. - void CreateExponentialRepresentation(const char* decimal_digits, - int length, - int exponent, - StringBuilder* result_builder) const; - // Creates a decimal representation (i.e 1234.5678). - void CreateDecimalRepresentation(const char* decimal_digits, - int length, - int decimal_point, - int digits_after_point, - StringBuilder* result_builder) const; - - const int flags_; - const char* const infinity_symbol_; - const char* const nan_symbol_; - const char exponent_character_; - const int decimal_in_shortest_low_; - const int decimal_in_shortest_high_; - const int max_leading_padding_zeroes_in_precision_mode_; - const int max_trailing_padding_zeroes_in_precision_mode_; -#endif // not needed for ICU - - DC_DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter); -}; - - -class StringToDoubleConverter { - public: - // Enumeration for allowing octals and ignoring junk when converting - // strings to numbers. - enum Flags { - NO_FLAGS = 0, - ALLOW_HEX = 1, - ALLOW_OCTALS = 2, - ALLOW_TRAILING_JUNK = 4, - ALLOW_LEADING_SPACES = 8, - ALLOW_TRAILING_SPACES = 16, - ALLOW_SPACES_AFTER_SIGN = 32, - ALLOW_CASE_INSENSIBILITY = 64, - ALLOW_HEX_FLOATS = 128, - }; - - static const uc16 kNoSeparator = '\0'; - - // Flags should be a bit-or combination of the possible Flags-enum. - // - NO_FLAGS: no special flags. - // - ALLOW_HEX: recognizes the prefix "0x". Hex numbers may only be integers. - // Ex: StringToDouble("0x1234") -> 4660.0 - // In StringToDouble("0x1234.56") the characters ".56" are trailing - // junk. The result of the call is hence dependent on - // the ALLOW_TRAILING_JUNK flag and/or the junk value. - // With this flag "0x" is a junk-string. Even with ALLOW_TRAILING_JUNK, - // the string will not be parsed as "0" followed by junk. - // - // - ALLOW_OCTALS: recognizes the prefix "0" for octals: - // If a sequence of octal digits starts with '0', then the number is - // read as octal integer. Octal numbers may only be integers. - // Ex: StringToDouble("01234") -> 668.0 - // StringToDouble("012349") -> 12349.0 // Not a sequence of octal - // // digits. - // In StringToDouble("01234.56") the characters ".56" are trailing - // junk. The result of the call is hence dependent on - // the ALLOW_TRAILING_JUNK flag and/or the junk value. - // In StringToDouble("01234e56") the characters "e56" are trailing - // junk, too. - // - ALLOW_TRAILING_JUNK: ignore trailing characters that are not part of - // a double literal. - // - ALLOW_LEADING_SPACES: skip over leading whitespace, including spaces, - // new-lines, and tabs. - // - ALLOW_TRAILING_SPACES: ignore trailing whitespace. - // - ALLOW_SPACES_AFTER_SIGN: ignore whitespace after the sign. - // Ex: StringToDouble("- 123.2") -> -123.2. - // StringToDouble("+ 123.2") -> 123.2 - // - ALLOW_CASE_INSENSIBILITY: ignore case of characters for special values: - // infinity and nan. - // - ALLOW_HEX_FLOATS: allows hexadecimal float literals. - // This *must* start with "0x" and separate the exponent with "p". - // Examples: 0x1.2p3 == 9.0 - // 0x10.1p0 == 16.0625 - // ALLOW_HEX and ALLOW_HEX_FLOATS are indendent. - // - // empty_string_value is returned when an empty string is given as input. - // If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a string - // containing only spaces is converted to the 'empty_string_value', too. - // - // junk_string_value is returned when - // a) ALLOW_TRAILING_JUNK is not set, and a junk character (a character not - // part of a double-literal) is found. - // b) ALLOW_TRAILING_JUNK is set, but the string does not start with a - // double literal. - // - // infinity_symbol and nan_symbol are strings that are used to detect - // inputs that represent infinity and NaN. They can be null, in which case - // they are ignored. - // The conversion routine first reads any possible signs. Then it compares the - // following character of the input-string with the first character of - // the infinity, and nan-symbol. If either matches, the function assumes, that - // a match has been found, and expects the following input characters to match - // the remaining characters of the special-value symbol. - // This means that the following restrictions apply to special-value symbols: - // - they must not start with signs ('+', or '-'), - // - they must not have the same first character. - // - they must not start with digits. - // - // If the separator character is not kNoSeparator, then that specific - // character is ignored when in between two valid digits of the significant. - // It is not allowed to appear in the exponent. - // It is not allowed to lead or trail the number. - // It is not allowed to appear twice next to each other. - // - // Examples: - // flags = ALLOW_HEX | ALLOW_TRAILING_JUNK, - // empty_string_value = 0.0, - // junk_string_value = NaN, - // infinity_symbol = "infinity", - // nan_symbol = "nan": - // StringToDouble("0x1234") -> 4660.0. - // StringToDouble("0x1234K") -> 4660.0. - // StringToDouble("") -> 0.0 // empty_string_value. - // StringToDouble(" ") -> NaN // junk_string_value. - // StringToDouble(" 1") -> NaN // junk_string_value. - // StringToDouble("0x") -> NaN // junk_string_value. - // StringToDouble("-123.45") -> -123.45. - // StringToDouble("--123.45") -> NaN // junk_string_value. - // StringToDouble("123e45") -> 123e45. - // StringToDouble("123E45") -> 123e45. - // StringToDouble("123e+45") -> 123e45. - // StringToDouble("123E-45") -> 123e-45. - // StringToDouble("123e") -> 123.0 // trailing junk ignored. - // StringToDouble("123e-") -> 123.0 // trailing junk ignored. - // StringToDouble("+NaN") -> NaN // NaN string literal. - // StringToDouble("-infinity") -> -inf. // infinity literal. - // StringToDouble("Infinity") -> NaN // junk_string_value. - // - // flags = ALLOW_OCTAL | ALLOW_LEADING_SPACES, - // empty_string_value = 0.0, - // junk_string_value = NaN, - // infinity_symbol = NULL, - // nan_symbol = NULL: - // StringToDouble("0x1234") -> NaN // junk_string_value. - // StringToDouble("01234") -> 668.0. - // StringToDouble("") -> 0.0 // empty_string_value. - // StringToDouble(" ") -> 0.0 // empty_string_value. - // StringToDouble(" 1") -> 1.0 - // StringToDouble("0x") -> NaN // junk_string_value. - // StringToDouble("0123e45") -> NaN // junk_string_value. - // StringToDouble("01239E45") -> 1239e45. - // StringToDouble("-infinity") -> NaN // junk_string_value. - // StringToDouble("NaN") -> NaN // junk_string_value. - // - // flags = NO_FLAGS, - // separator = ' ': - // StringToDouble("1 2 3 4") -> 1234.0 - // StringToDouble("1 2") -> NaN // junk_string_value - // StringToDouble("1 000 000.0") -> 1000000.0 - // StringToDouble("1.000 000") -> 1.0 - // StringToDouble("1.0e1 000") -> NaN // junk_string_value - StringToDoubleConverter(int flags, - double empty_string_value, - double junk_string_value, - const char* infinity_symbol, - const char* nan_symbol, - uc16 separator = kNoSeparator) - : flags_(flags), - empty_string_value_(empty_string_value), - junk_string_value_(junk_string_value), - infinity_symbol_(infinity_symbol), - nan_symbol_(nan_symbol), - separator_(separator) { - } - - // Performs the conversion. - // The output parameter 'processed_characters_count' is set to the number - // of characters that have been processed to read the number. - // Spaces than are processed with ALLOW_{LEADING|TRAILING}_SPACES are included - // in the 'processed_characters_count'. Trailing junk is never included. - double StringToDouble(const char* buffer, - int length, - int* processed_characters_count) const; - - // Same as StringToDouble above but for 16 bit characters. - double StringToDouble(const uc16* buffer, - int length, - int* processed_characters_count) const; - - // Same as StringToDouble but reads a float. - // Note that this is not equivalent to static_cast<float>(StringToDouble(...)) - // due to potential double-rounding. - float StringToFloat(const char* buffer, - int length, - int* processed_characters_count) const; - - // Same as StringToFloat above but for 16 bit characters. - float StringToFloat(const uc16* buffer, - int length, - int* processed_characters_count) const; - - private: - const int flags_; - const double empty_string_value_; - const double junk_string_value_; - const char* const infinity_symbol_; - const char* const nan_symbol_; - const uc16 separator_; - - template <class Iterator> - double StringToIeee(Iterator start_pointer, - int length, - bool read_as_double, - int* processed_characters_count) const; - - DC_DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter); -}; - -} // namespace double_conversion - -// ICU PATCH: Close ICU namespace -U_NAMESPACE_END +#include "double-conversion-string-to-double.h" +#include "double-conversion-double-to-string.h" #endif // DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_ #endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING diff --git a/deps/icu-small/source/i18n/dtfmtsym.cpp b/deps/icu-small/source/i18n/dtfmtsym.cpp index 04aa01eb4c..9dde66c1fb 100644 --- a/deps/icu-small/source/i18n/dtfmtsym.cpp +++ b/deps/icu-small/source/i18n/dtfmtsym.cpp @@ -1246,7 +1246,7 @@ const UnicodeString** DateFormatSymbols::getZoneStrings(int32_t& rowCount, int32_t& columnCount) const { const UnicodeString **result = NULL; - static UMutex LOCK = U_MUTEX_INITIALIZER; + static UMutex LOCK; umtx_lock(&LOCK); if (fZoneStrings == NULL) { @@ -2177,16 +2177,16 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError // The ordering of the following statements is important. if (fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].isEmpty()) { fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]); - }; + } if (fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].isEmpty()) { fLeapMonthPatterns[kLeapMonthPatternFormatNarrow].setTo(fLeapMonthPatterns[kLeapMonthPatternStandaloneNarrow]); - }; + } if (fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].isEmpty()) { fLeapMonthPatterns[kLeapMonthPatternStandaloneWide].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatWide]); - }; + } if (fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].isEmpty()) { fLeapMonthPatterns[kLeapMonthPatternStandaloneAbbrev].setTo(fLeapMonthPatterns[kLeapMonthPatternFormatAbbrev]); - }; + } // end of hack fLeapMonthPatternsCount = kMonthPatternsCount; } else { @@ -2338,11 +2338,21 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError assignArray(fStandaloneNarrowMonths, fStandaloneNarrowMonthsCount, fShortMonths, fShortMonthsCount); } - // Load AM/PM markers + // Load AM/PM markers; if wide or narrow not available, use short + UErrorCode ampmStatus = U_ZERO_ERROR; initField(&fAmPms, fAmPmsCount, calendarSink, - buildResourcePath(path, gAmPmMarkersTag, status), status); + buildResourcePath(path, gAmPmMarkersTag, ampmStatus), ampmStatus); + if (U_FAILURE(ampmStatus)) { + initField(&fAmPms, fAmPmsCount, calendarSink, + buildResourcePath(path, gAmPmMarkersAbbrTag, status), status); + } + ampmStatus = U_ZERO_ERROR; initField(&fNarrowAmPms, fNarrowAmPmsCount, calendarSink, - buildResourcePath(path, gAmPmMarkersNarrowTag, status), status); + buildResourcePath(path, gAmPmMarkersNarrowTag, ampmStatus), ampmStatus); + if (U_FAILURE(ampmStatus)) { + initField(&fNarrowAmPms, fNarrowAmPmsCount, calendarSink, + buildResourcePath(path, gAmPmMarkersAbbrTag, status), status); + } // Load quarters initField(&fQuarters, fQuartersCount, calendarSink, diff --git a/deps/icu-small/source/i18n/dtitv_impl.h b/deps/icu-small/source/i18n/dtitv_impl.h index 18fe0b8c9b..7c4d8a7214 100644 --- a/deps/icu-small/source/i18n/dtitv_impl.h +++ b/deps/icu-small/source/i18n/dtitv_impl.h @@ -88,7 +88,7 @@ #define MAX_E_COUNT 5 #define MAX_M_COUNT 5 //#define MAX_INTERVAL_INDEX 4 -#define MAX_POSITIVE_INT 56632; +#define MAX_POSITIVE_INT 56632 #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/dtitvfmt.cpp b/deps/icu-small/source/i18n/dtitvfmt.cpp index 0e124f5624..f47e7708cc 100644 --- a/deps/icu-small/source/i18n/dtitvfmt.cpp +++ b/deps/icu-small/source/i18n/dtitvfmt.cpp @@ -82,10 +82,7 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DateIntervalFormat) // Mutex, protects access to fDateFormat, fFromCalendar and fToCalendar. // Needed because these data members are modified by const methods of DateIntervalFormat. -static UMutex *gFormatterMutex() { - static UMutex m = U_MUTEX_INITIALIZER; - return &m; -} +static UMutex gFormatterMutex; DateIntervalFormat* U_EXPORT2 DateIntervalFormat::createInstance(const UnicodeString& skeleton, @@ -171,9 +168,9 @@ DateIntervalFormat::operator=(const DateIntervalFormat& itvfmt) { delete fTimePattern; delete fDateTimeFormat; { - Mutex lock(gFormatterMutex()); + Mutex lock(&gFormatterMutex); if ( itvfmt.fDateFormat ) { - fDateFormat = (SimpleDateFormat*)itvfmt.fDateFormat->clone(); + fDateFormat = itvfmt.fDateFormat->clone(); } else { fDateFormat = NULL; } @@ -199,9 +196,9 @@ DateIntervalFormat::operator=(const DateIntervalFormat& itvfmt) { fIntervalPatterns[i] = itvfmt.fIntervalPatterns[i]; } fLocale = itvfmt.fLocale; - fDatePattern = (itvfmt.fDatePattern)? (UnicodeString*)itvfmt.fDatePattern->clone(): NULL; - fTimePattern = (itvfmt.fTimePattern)? (UnicodeString*)itvfmt.fTimePattern->clone(): NULL; - fDateTimeFormat = (itvfmt.fDateTimeFormat)? (UnicodeString*)itvfmt.fDateTimeFormat->clone(): NULL; + fDatePattern = (itvfmt.fDatePattern)? itvfmt.fDatePattern->clone(): NULL; + fTimePattern = (itvfmt.fTimePattern)? itvfmt.fTimePattern->clone(): NULL; + fDateTimeFormat = (itvfmt.fDateTimeFormat)? itvfmt.fDateTimeFormat->clone(): NULL; } return *this; } @@ -218,8 +215,8 @@ DateIntervalFormat::~DateIntervalFormat() { } -Format* -DateIntervalFormat::clone(void) const { +DateIntervalFormat* +DateIntervalFormat::clone() const { return new DateIntervalFormat(*this); } @@ -233,7 +230,7 @@ DateIntervalFormat::operator==(const Format& other) const { if ((fInfo != fmt->fInfo) && (fInfo == NULL || fmt->fInfo == NULL)) {return FALSE;} if (fInfo && fmt->fInfo && (*fInfo != *fmt->fInfo )) {return FALSE;} { - Mutex lock(gFormatterMutex()); + Mutex lock(&gFormatterMutex); if (fDateFormat != fmt->fDateFormat && (fDateFormat == NULL || fmt->fDateFormat == NULL)) {return FALSE;} if (fDateFormat && fmt->fDateFormat && (*fDateFormat != *fmt->fDateFormat)) {return FALSE;} } @@ -295,7 +292,7 @@ DateIntervalFormat::format(const DateInterval* dtInterval, handler.setAcceptFirstOnly(TRUE); int8_t ignore; - Mutex lock(gFormatterMutex()); + Mutex lock(&gFormatterMutex); return formatIntervalImpl(*dtInterval, appendTo, ignore, handler, status); } @@ -312,7 +309,7 @@ FormattedDateInterval DateIntervalFormat::formatToValue( auto handler = result->getHandler(status); handler.setCategory(UFIELD_CATEGORY_DATE); { - Mutex lock(gFormatterMutex()); + Mutex lock(&gFormatterMutex); formatIntervalImpl(dtInterval, string, firstIndex, handler, status); } handler.getError(status); @@ -344,7 +341,7 @@ DateIntervalFormat::format(Calendar& fromCalendar, handler.setAcceptFirstOnly(TRUE); int8_t ignore; - Mutex lock(gFormatterMutex()); + Mutex lock(&gFormatterMutex); return formatImpl(fromCalendar, toCalendar, appendTo, ignore, handler, status); } @@ -362,7 +359,7 @@ FormattedDateInterval DateIntervalFormat::formatToValue( auto handler = result->getHandler(status); handler.setCategory(UFIELD_CATEGORY_DATE); { - Mutex lock(gFormatterMutex()); + Mutex lock(&gFormatterMutex); formatImpl(fromCalendar, toCalendar, string, firstIndex, handler, status); } handler.getError(status); @@ -600,7 +597,7 @@ const TimeZone& DateIntervalFormat::getTimeZone() const { if (fDateFormat != NULL) { - Mutex lock(gFormatterMutex()); + Mutex lock(&gFormatterMutex); return fDateFormat->getTimeZone(); } // If fDateFormat is NULL (unexpected), create default timezone. diff --git a/deps/icu-small/source/i18n/dtitvinf.cpp b/deps/icu-small/source/i18n/dtitvinf.cpp index c0a6980e55..35ee8c1626 100644 --- a/deps/icu-small/source/i18n/dtitvinf.cpp +++ b/deps/icu-small/source/i18n/dtitvinf.cpp @@ -42,7 +42,9 @@ U_NAMESPACE_BEGIN #ifdef DTITVINF_DEBUG -#define PRINTMESG(msg) { std::cout << "(" << __FILE__ << ":" << __LINE__ << ") " << msg << "\n"; } +#define PRINTMESG(msg) UPRV_BLOCK_MACRO_BEGIN { \ + std::cout << "(" << __FILE__ << ":" << __LINE__ << ") " << msg << "\n"; \ +} UPRV_BLOCK_MACRO_END #endif UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DateIntervalInfo) diff --git a/deps/icu-small/source/i18n/dtptngen.cpp b/deps/icu-small/source/i18n/dtptngen.cpp index 9ca29a3cc7..50a377259a 100644 --- a/deps/icu-small/source/i18n/dtptngen.cpp +++ b/deps/icu-small/source/i18n/dtptngen.cpp @@ -28,6 +28,7 @@ #include "unicode/ures.h" #include "unicode/ustring.h" #include "unicode/rep.h" +#include "unicode/region.h" #include "cpputils.h" #include "mutex.h" #include "umutex.h" @@ -613,29 +614,56 @@ U_CFUNC void U_CALLCONV DateTimePatternGenerator::loadAllowedHourFormatsData(UEr ures_getAllItemsWithFallback(rb.getAlias(), "timeData", sink, status); } -void DateTimePatternGenerator::getAllowedHourFormats(const Locale &locale, UErrorCode &status) { - if (U_FAILURE(status)) { return; } - Locale maxLocale(locale); - maxLocale.addLikelySubtags(status); - if (U_FAILURE(status)) { - return; - } - - const char *country = maxLocale.getCountry(); - if (*country == '\0') { country = "001"; } - const char *language = maxLocale.getLanguage(); - +static int32_t* getAllowedHourFormatsLangCountry(const char* language, const char* country, UErrorCode& status) { CharString langCountry; - langCountry.append(language, static_cast<int32_t>(uprv_strlen(language)), status); + langCountry.append(language, status); langCountry.append('_', status); - langCountry.append(country, static_cast<int32_t>(uprv_strlen(country)), status); + langCountry.append(country, status); - int32_t *allowedFormats; + int32_t* allowedFormats; allowedFormats = (int32_t *)uhash_get(localeToAllowedHourFormatsMap, langCountry.data()); if (allowedFormats == nullptr) { allowedFormats = (int32_t *)uhash_get(localeToAllowedHourFormatsMap, const_cast<char *>(country)); } + return allowedFormats; +} + +void DateTimePatternGenerator::getAllowedHourFormats(const Locale &locale, UErrorCode &status) { + if (U_FAILURE(status)) { return; } + + const char *language = locale.getLanguage(); + const char *country = locale.getCountry(); + Locale maxLocale; // must be here for correct lifetime + if (*language == '\0' || *country == '\0') { + maxLocale = locale; + UErrorCode localStatus = U_ZERO_ERROR; + maxLocale.addLikelySubtags(localStatus); + if (U_SUCCESS(localStatus)) { + language = maxLocale.getLanguage(); + country = maxLocale.getCountry(); + } + } + if (*language == '\0') { + // Unexpected, but fail gracefully + language = "und"; + } + if (*country == '\0') { + country = "001"; + } + + int32_t* allowedFormats = getAllowedHourFormatsLangCountry(language, country, status); + + // Check if the region has an alias + if (allowedFormats == nullptr) { + UErrorCode localStatus = U_ZERO_ERROR; + const Region* region = Region::getInstance(country, localStatus); + if (U_SUCCESS(localStatus)) { + country = region->getRegionCode(); // the real region code + allowedFormats = getAllowedHourFormatsLangCountry(language, country, status); + } + } + if (allowedFormats != nullptr) { // Lookup is successful // Here allowedFormats points to a list consisting of key for preferredFormat, // followed by one or more keys for allowedFormats, then followed by ALLOWED_HOUR_FORMAT_UNKNOWN. @@ -787,6 +815,7 @@ void DateTimePatternGenerator::getCalendarTypeToUse(const Locale& locale, CharString& destination, UErrorCode& err) { destination.clear().append(DT_DateTimeGregorianTag, -1, err); // initial default if ( U_SUCCESS(err) ) { + UErrorCode localStatus = U_ZERO_ERROR; char localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY]; // obtain a locale that always has the calendar key value that should be used ures_getFunctionalEquivalent( @@ -798,8 +827,7 @@ DateTimePatternGenerator::getCalendarTypeToUse(const Locale& locale, CharString& locale.getName(), nullptr, FALSE, - &err); - if (U_FAILURE(err)) { return; } + &localStatus); localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY-1] = 0; // ensure null termination // now get the calendar key value from that locale char calendarType[ULOC_KEYWORDS_CAPACITY]; @@ -808,13 +836,17 @@ DateTimePatternGenerator::getCalendarTypeToUse(const Locale& locale, CharString& "calendar", calendarType, ULOC_KEYWORDS_CAPACITY, - &err); - if (U_FAILURE(err)) { return; } + &localStatus); + // If the input locale was invalid, don't fail with missing resource error, instead + // continue with default of Gregorian. + if (U_FAILURE(localStatus) && localStatus != U_MISSING_RESOURCE_ERROR) { + err = localStatus; + return; + } if (calendarTypeLen < ULOC_KEYWORDS_CAPACITY) { destination.clear().append(calendarType, -1, err); if (U_FAILURE(err)) { return; } } - err = U_ZERO_ERROR; } } @@ -2543,7 +2575,8 @@ UChar SkeletonFields::getFirstChar() const { } -PtnSkeleton::PtnSkeleton() { +PtnSkeleton::PtnSkeleton() + : addedDefaultDayPeriod(FALSE) { } PtnSkeleton::PtnSkeleton(const PtnSkeleton& other) { @@ -2554,6 +2587,7 @@ void PtnSkeleton::copyFrom(const PtnSkeleton& other) { uprv_memcpy(type, other.type, sizeof(type)); original.copyFrom(other.original); baseOriginal.copyFrom(other.baseOriginal); + addedDefaultDayPeriod = other.addedDefaultDayPeriod; } void PtnSkeleton::clear() { diff --git a/deps/icu-small/source/i18n/esctrn.cpp b/deps/icu-small/source/i18n/esctrn.cpp index 900bed7e45..ba0e4c2c7b 100644 --- a/deps/icu-small/source/i18n/esctrn.cpp +++ b/deps/icu-small/source/i18n/esctrn.cpp @@ -122,7 +122,7 @@ EscapeTransliterator::~EscapeTransliterator() { /** * Transliterator API. */ -Transliterator* EscapeTransliterator::clone() const { +EscapeTransliterator* EscapeTransliterator::clone() const { return new EscapeTransliterator(*this); } diff --git a/deps/icu-small/source/i18n/esctrn.h b/deps/icu-small/source/i18n/esctrn.h index 60ecc74b49..2a2c6dcfe9 100644 --- a/deps/icu-small/source/i18n/esctrn.h +++ b/deps/icu-small/source/i18n/esctrn.h @@ -115,7 +115,7 @@ class EscapeTransliterator : public Transliterator { /** * Transliterator API. */ - virtual Transliterator* clone() const; + virtual EscapeTransliterator* clone() const; /** * ICU "poor man's RTTI", returns a UClassID for the actual class. diff --git a/deps/icu-small/source/i18n/ethpccal.cpp b/deps/icu-small/source/i18n/ethpccal.cpp index 4377c59b32..0b8ad0e814 100644 --- a/deps/icu-small/source/i18n/ethpccal.cpp +++ b/deps/icu-small/source/i18n/ethpccal.cpp @@ -46,7 +46,7 @@ EthiopicCalendar::~EthiopicCalendar() { } -Calendar* +EthiopicCalendar* EthiopicCalendar::clone() const { return new EthiopicCalendar(*this); diff --git a/deps/icu-small/source/i18n/ethpccal.h b/deps/icu-small/source/i18n/ethpccal.h index 5fae2fb1be..179a20e853 100644 --- a/deps/icu-small/source/i18n/ethpccal.h +++ b/deps/icu-small/source/i18n/ethpccal.h @@ -141,7 +141,7 @@ public: * @return return a polymorphic copy of this calendar. * @internal */ - virtual Calendar* clone() const; + virtual EthiopicCalendar* clone() const; /** * return the calendar type, "ethiopic" diff --git a/deps/icu-small/source/i18n/fmtable.cpp b/deps/icu-small/source/i18n/fmtable.cpp index 9baa5ff480..10a6fdb0ff 100644 --- a/deps/icu-small/source/i18n/fmtable.cpp +++ b/deps/icu-small/source/i18n/fmtable.cpp @@ -736,7 +736,7 @@ CharString *Formattable::internalGetCharString(UErrorCode &status) { fDecimalStr->append("Infinity", status); } else if (fDecimalQuantity->isNaN()) { fDecimalStr->append("NaN", status); - } else if (fDecimalQuantity->isZero()) { + } else if (fDecimalQuantity->isZeroish()) { fDecimalStr->append("0", -1, status); } else if (fType==kLong || fType==kInt64 || // use toPlainString for integer types (fDecimalQuantity->getMagnitude() != INT32_MIN && std::abs(fDecimalQuantity->getMagnitude()) < 5)) { diff --git a/deps/icu-small/source/i18n/number_stringbuilder.cpp b/deps/icu-small/source/i18n/formatted_string_builder.cpp index 03300b33ac..3024bff6ad 100644 --- a/deps/icu-small/source/i18n/number_stringbuilder.cpp +++ b/deps/icu-small/source/i18n/formatted_string_builder.cpp @@ -5,14 +5,9 @@ #if !UCONFIG_NO_FORMATTING -#include "number_stringbuilder.h" -#include "static_unicode_sets.h" +#include "formatted_string_builder.h" +#include "unicode/ustring.h" #include "unicode/utf16.h" -#include "number_utils.h" - -using namespace icu; -using namespace icu::number; -using namespace icu::number::impl; namespace { @@ -34,7 +29,10 @@ inline void uprv_memmove2(void* dest, const void* src, size_t len) { } // namespace -NumberStringBuilder::NumberStringBuilder() { + +U_NAMESPACE_BEGIN + +FormattedStringBuilder::FormattedStringBuilder() { #if U_DEBUG // Initializing the memory to non-zero helps catch some bugs that involve // reading from an improperly terminated string. @@ -44,18 +42,18 @@ NumberStringBuilder::NumberStringBuilder() { #endif } -NumberStringBuilder::~NumberStringBuilder() { +FormattedStringBuilder::~FormattedStringBuilder() { if (fUsingHeap) { uprv_free(fChars.heap.ptr); uprv_free(fFields.heap.ptr); } } -NumberStringBuilder::NumberStringBuilder(const NumberStringBuilder &other) { +FormattedStringBuilder::FormattedStringBuilder(const FormattedStringBuilder &other) { *this = other; } -NumberStringBuilder &NumberStringBuilder::operator=(const NumberStringBuilder &other) { +FormattedStringBuilder &FormattedStringBuilder::operator=(const FormattedStringBuilder &other) { // Check for self-assignment if (this == &other) { return *this; @@ -78,7 +76,7 @@ NumberStringBuilder &NumberStringBuilder::operator=(const NumberStringBuilder &o // UErrorCode is not available; fail silently. uprv_free(newChars); uprv_free(newFields); - *this = NumberStringBuilder(); // can't fail + *this = FormattedStringBuilder(); // can't fail return *this; } @@ -97,15 +95,15 @@ NumberStringBuilder &NumberStringBuilder::operator=(const NumberStringBuilder &o return *this; } -int32_t NumberStringBuilder::length() const { +int32_t FormattedStringBuilder::length() const { return fLength; } -int32_t NumberStringBuilder::codePointCount() const { +int32_t FormattedStringBuilder::codePointCount() const { return u_countChar32(getCharPtr() + fZero, fLength); } -UChar32 NumberStringBuilder::getFirstCodePoint() const { +UChar32 FormattedStringBuilder::getFirstCodePoint() const { if (fLength == 0) { return -1; } @@ -114,7 +112,7 @@ UChar32 NumberStringBuilder::getFirstCodePoint() const { return cp; } -UChar32 NumberStringBuilder::getLastCodePoint() const { +UChar32 FormattedStringBuilder::getLastCodePoint() const { if (fLength == 0) { return -1; } @@ -125,13 +123,13 @@ UChar32 NumberStringBuilder::getLastCodePoint() const { return cp; } -UChar32 NumberStringBuilder::codePointAt(int32_t index) const { +UChar32 FormattedStringBuilder::codePointAt(int32_t index) const { UChar32 cp; U16_GET(getCharPtr() + fZero, 0, index, fLength, cp); return cp; } -UChar32 NumberStringBuilder::codePointBefore(int32_t index) const { +UChar32 FormattedStringBuilder::codePointBefore(int32_t index) const { int32_t offset = index; U16_BACK_1(getCharPtr() + fZero, 0, offset); UChar32 cp; @@ -139,19 +137,15 @@ UChar32 NumberStringBuilder::codePointBefore(int32_t index) const { return cp; } -NumberStringBuilder &NumberStringBuilder::clear() { +FormattedStringBuilder &FormattedStringBuilder::clear() { // TODO: Reset the heap here? fZero = getCapacity() / 2; fLength = 0; return *this; } -int32_t NumberStringBuilder::appendCodePoint(UChar32 codePoint, Field field, UErrorCode &status) { - return insertCodePoint(fLength, codePoint, field, status); -} - int32_t -NumberStringBuilder::insertCodePoint(int32_t index, UChar32 codePoint, Field field, UErrorCode &status) { +FormattedStringBuilder::insertCodePoint(int32_t index, UChar32 codePoint, Field field, UErrorCode &status) { int32_t count = U16_LENGTH(codePoint); int32_t position = prepareForInsert(index, count, status); if (U_FAILURE(status)) { @@ -168,11 +162,7 @@ NumberStringBuilder::insertCodePoint(int32_t index, UChar32 codePoint, Field fie return count; } -int32_t NumberStringBuilder::append(const UnicodeString &unistr, Field field, UErrorCode &status) { - return insert(fLength, unistr, field, status); -} - -int32_t NumberStringBuilder::insert(int32_t index, const UnicodeString &unistr, Field field, +int32_t FormattedStringBuilder::insert(int32_t index, const UnicodeString &unistr, Field field, UErrorCode &status) { if (unistr.length() == 0) { // Nothing to insert. @@ -186,7 +176,7 @@ int32_t NumberStringBuilder::insert(int32_t index, const UnicodeString &unistr, } int32_t -NumberStringBuilder::insert(int32_t index, const UnicodeString &unistr, int32_t start, int32_t end, +FormattedStringBuilder::insert(int32_t index, const UnicodeString &unistr, int32_t start, int32_t end, Field field, UErrorCode &status) { int32_t count = end - start; int32_t position = prepareForInsert(index, count, status); @@ -201,7 +191,7 @@ NumberStringBuilder::insert(int32_t index, const UnicodeString &unistr, int32_t } int32_t -NumberStringBuilder::splice(int32_t startThis, int32_t endThis, const UnicodeString &unistr, +FormattedStringBuilder::splice(int32_t startThis, int32_t endThis, const UnicodeString &unistr, int32_t startOther, int32_t endOther, Field field, UErrorCode& status) { int32_t thisLength = endThis - startThis; int32_t otherLength = endOther - startOther; @@ -224,12 +214,12 @@ NumberStringBuilder::splice(int32_t startThis, int32_t endThis, const UnicodeSt return count; } -int32_t NumberStringBuilder::append(const NumberStringBuilder &other, UErrorCode &status) { +int32_t FormattedStringBuilder::append(const FormattedStringBuilder &other, UErrorCode &status) { return insert(fLength, other, status); } int32_t -NumberStringBuilder::insert(int32_t index, const NumberStringBuilder &other, UErrorCode &status) { +FormattedStringBuilder::insert(int32_t index, const FormattedStringBuilder &other, UErrorCode &status) { if (this == &other) { status = U_ILLEGAL_ARGUMENT_ERROR; return 0; @@ -250,7 +240,7 @@ NumberStringBuilder::insert(int32_t index, const NumberStringBuilder &other, UEr return count; } -void NumberStringBuilder::writeTerminator(UErrorCode& status) { +void FormattedStringBuilder::writeTerminator(UErrorCode& status) { int32_t position = prepareForInsert(fLength, 1, status); if (U_FAILURE(status)) { return; @@ -260,7 +250,7 @@ void NumberStringBuilder::writeTerminator(UErrorCode& status) { fLength--; } -int32_t NumberStringBuilder::prepareForInsert(int32_t index, int32_t count, UErrorCode &status) { +int32_t FormattedStringBuilder::prepareForInsert(int32_t index, int32_t count, UErrorCode &status) { U_ASSERT(index >= 0); U_ASSERT(index <= fLength); U_ASSERT(count >= 0); @@ -279,7 +269,7 @@ int32_t NumberStringBuilder::prepareForInsert(int32_t index, int32_t count, UErr } } -int32_t NumberStringBuilder::prepareForInsertHelper(int32_t index, int32_t count, UErrorCode &status) { +int32_t FormattedStringBuilder::prepareForInsertHelper(int32_t index, int32_t count, UErrorCode &status) { int32_t oldCapacity = getCapacity(); int32_t oldZero = fZero; char16_t *oldChars = getCharPtr(); @@ -342,7 +332,7 @@ int32_t NumberStringBuilder::prepareForInsertHelper(int32_t index, int32_t count return fZero + index; } -int32_t NumberStringBuilder::remove(int32_t index, int32_t count) { +int32_t FormattedStringBuilder::remove(int32_t index, int32_t count) { // TODO: Reset the heap here? (If the string after removal can fit on stack?) int32_t position = index + fZero; uprv_memmove2(getCharPtr() + position, @@ -355,18 +345,18 @@ int32_t NumberStringBuilder::remove(int32_t index, int32_t count) { return position; } -UnicodeString NumberStringBuilder::toUnicodeString() const { +UnicodeString FormattedStringBuilder::toUnicodeString() const { return UnicodeString(getCharPtr() + fZero, fLength); } -const UnicodeString NumberStringBuilder::toTempUnicodeString() const { +const UnicodeString FormattedStringBuilder::toTempUnicodeString() const { // Readonly-alias constructor: return UnicodeString(FALSE, getCharPtr() + fZero, fLength); } -UnicodeString NumberStringBuilder::toDebugString() const { +UnicodeString FormattedStringBuilder::toDebugString() const { UnicodeString sb; - sb.append(u"<NumberStringBuilder [", -1); + sb.append(u"<FormattedStringBuilder [", -1); sb.append(toUnicodeString()); sb.append(u"] [", -1); for (int i = 0; i < fLength; i++) { @@ -419,11 +409,11 @@ UnicodeString NumberStringBuilder::toDebugString() const { return sb; } -const char16_t *NumberStringBuilder::chars() const { +const char16_t *FormattedStringBuilder::chars() const { return getCharPtr() + fZero; } -bool NumberStringBuilder::contentEquals(const NumberStringBuilder &other) const { +bool FormattedStringBuilder::contentEquals(const FormattedStringBuilder &other) const { if (fLength != other.fLength) { return false; } @@ -435,136 +425,7 @@ bool NumberStringBuilder::contentEquals(const NumberStringBuilder &other) const return true; } -bool NumberStringBuilder::nextFieldPosition(FieldPosition& fp, UErrorCode& status) const { - int32_t rawField = fp.getField(); - - if (rawField == FieldPosition::DONT_CARE) { - return FALSE; - } - - if (rawField < 0 || rawField >= UNUM_FIELD_COUNT) { - status = U_ILLEGAL_ARGUMENT_ERROR; - return FALSE; - } - - ConstrainedFieldPosition cfpos; - cfpos.constrainField(UFIELD_CATEGORY_NUMBER, rawField); - cfpos.setState(UFIELD_CATEGORY_NUMBER, rawField, fp.getBeginIndex(), fp.getEndIndex()); - if (nextPosition(cfpos, 0, status)) { - fp.setBeginIndex(cfpos.getStart()); - fp.setEndIndex(cfpos.getLimit()); - return true; - } - - // Special case: fraction should start after integer if fraction is not present - if (rawField == UNUM_FRACTION_FIELD && fp.getEndIndex() == 0) { - bool inside = false; - int32_t i = fZero; - for (; i < fZero + fLength; i++) { - if (isIntOrGroup(getFieldPtr()[i]) || getFieldPtr()[i] == UNUM_DECIMAL_SEPARATOR_FIELD) { - inside = true; - } else if (inside) { - break; - } - } - fp.setBeginIndex(i - fZero); - fp.setEndIndex(i - fZero); - } - - return false; -} - -void NumberStringBuilder::getAllFieldPositions(FieldPositionIteratorHandler& fpih, - UErrorCode& status) const { - ConstrainedFieldPosition cfpos; - while (nextPosition(cfpos, 0, status)) { - fpih.addAttribute(cfpos.getField(), cfpos.getStart(), cfpos.getLimit()); - } -} - -// Signal the end of the string using a field that doesn't exist and that is -// different from UNUM_FIELD_COUNT, which is used for "null number field". -static constexpr Field kEndField = 0xff; - -bool NumberStringBuilder::nextPosition(ConstrainedFieldPosition& cfpos, Field numericField, UErrorCode& /*status*/) const { - auto numericCAF = NumFieldUtils::expand(numericField); - int32_t fieldStart = -1; - Field currField = UNUM_FIELD_COUNT; - for (int32_t i = fZero + cfpos.getLimit(); i <= fZero + fLength; i++) { - Field _field = (i < fZero + fLength) ? getFieldPtr()[i] : kEndField; - // Case 1: currently scanning a field. - if (currField != UNUM_FIELD_COUNT) { - if (currField != _field) { - int32_t end = i - fZero; - // Grouping separators can be whitespace; don't throw them out! - if (currField != UNUM_GROUPING_SEPARATOR_FIELD) { - end = trimBack(i - fZero); - } - if (end <= fieldStart) { - // Entire field position is ignorable; skip. - fieldStart = -1; - currField = UNUM_FIELD_COUNT; - i--; // look at this index again - continue; - } - int32_t start = fieldStart; - if (currField != UNUM_GROUPING_SEPARATOR_FIELD) { - start = trimFront(start); - } - auto caf = NumFieldUtils::expand(currField); - cfpos.setState(caf.category, caf.field, start, end); - return true; - } - continue; - } - // Special case: coalesce the INTEGER if we are pointing at the end of the INTEGER. - if (cfpos.matchesField(UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD) - && i > fZero - // don't return the same field twice in a row: - && i - fZero > cfpos.getLimit() - && isIntOrGroup(getFieldPtr()[i - 1]) - && !isIntOrGroup(_field)) { - int j = i - 1; - for (; j >= fZero && isIntOrGroup(getFieldPtr()[j]); j--) {} - cfpos.setState(UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD, j - fZero + 1, i - fZero); - return true; - } - // Special case: coalesce NUMERIC if we are pointing at the end of the NUMERIC. - if (numericField != 0 - && cfpos.matchesField(numericCAF.category, numericCAF.field) - && i > fZero - // don't return the same field twice in a row: - && (i - fZero > cfpos.getLimit() - || cfpos.getCategory() != numericCAF.category - || cfpos.getField() != numericCAF.field) - && isNumericField(getFieldPtr()[i - 1]) - && !isNumericField(_field)) { - int j = i - 1; - for (; j >= fZero && isNumericField(getFieldPtr()[j]); j--) {} - cfpos.setState(numericCAF.category, numericCAF.field, j - fZero + 1, i - fZero); - return true; - } - // Special case: skip over INTEGER; will be coalesced later. - if (_field == UNUM_INTEGER_FIELD) { - _field = UNUM_FIELD_COUNT; - } - // Case 2: no field starting at this position. - if (_field == UNUM_FIELD_COUNT || _field == kEndField) { - continue; - } - // Case 3: check for field starting at this position - auto caf = NumFieldUtils::expand(_field); - if (cfpos.matchesField(caf.category, caf.field)) { - fieldStart = i - fZero; - currField = _field; - } - } - - U_ASSERT(currField == UNUM_FIELD_COUNT); - return false; -} - -bool NumberStringBuilder::containsField(Field field) const { +bool FormattedStringBuilder::containsField(Field field) const { for (int32_t i = 0; i < fLength; i++) { if (field == fieldAt(i)) { return true; @@ -573,27 +434,6 @@ bool NumberStringBuilder::containsField(Field field) const { return false; } -bool NumberStringBuilder::isIntOrGroup(Field field) { - return field == UNUM_INTEGER_FIELD - || field == UNUM_GROUPING_SEPARATOR_FIELD; -} - -bool NumberStringBuilder::isNumericField(Field field) { - return NumFieldUtils::isNumericField(field); -} - -int32_t NumberStringBuilder::trimBack(int32_t limit) const { - return unisets::get(unisets::DEFAULT_IGNORABLES)->spanBack( - getCharPtr() + fZero, - limit, - USET_SPAN_CONTAINED); -} - -int32_t NumberStringBuilder::trimFront(int32_t start) const { - return start + unisets::get(unisets::DEFAULT_IGNORABLES)->span( - getCharPtr() + fZero + start, - fLength - start, - USET_SPAN_CONTAINED); -} +U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/formatted_string_builder.h b/deps/icu-small/source/i18n/formatted_string_builder.h new file mode 100644 index 0000000000..2949ae73e0 --- /dev/null +++ b/deps/icu-small/source/i18n/formatted_string_builder.h @@ -0,0 +1,253 @@ +// © 2017 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING +#ifndef __NUMBER_STRINGBUILDER_H__ +#define __NUMBER_STRINGBUILDER_H__ + + +#include <cstdint> +#include "unicode/unum.h" // for UNUM_FIELD_COUNT +#include "cstring.h" +#include "uassert.h" +#include "fphdlimp.h" + +U_NAMESPACE_BEGIN + +class FormattedValueStringBuilderImpl; + +/** + * A StringBuilder optimized for formatting. It implements the following key + * features beyond a UnicodeString: + * + * <ol> + * <li>Efficient prepend as well as append. + * <li>Keeps tracks of Fields in an efficient manner. + * </ol> + * + * See also FormattedValueStringBuilderImpl. + * + * @author sffc (Shane Carr) + */ +class U_I18N_API FormattedStringBuilder : public UMemory { + private: + static const int32_t DEFAULT_CAPACITY = 40; + + template<typename T> + union ValueOrHeapArray { + T value[DEFAULT_CAPACITY]; + struct { + T *ptr; + int32_t capacity; + } heap; + }; + + public: + FormattedStringBuilder(); + + ~FormattedStringBuilder(); + + FormattedStringBuilder(const FormattedStringBuilder &other); + + // Convention: bottom 4 bits for field, top 4 bits for field category. + // Field category 0 implies the number category so that the number field + // literals can be directly passed as a Field type. + // See the helper functions in "StringBuilderFieldUtils" below. + typedef uint8_t Field; + + FormattedStringBuilder &operator=(const FormattedStringBuilder &other); + + int32_t length() const; + + int32_t codePointCount() const; + + inline char16_t charAt(int32_t index) const { + U_ASSERT(index >= 0); + U_ASSERT(index < fLength); + return getCharPtr()[fZero + index]; + } + + inline Field fieldAt(int32_t index) const { + U_ASSERT(index >= 0); + U_ASSERT(index < fLength); + return getFieldPtr()[fZero + index]; + } + + UChar32 getFirstCodePoint() const; + + UChar32 getLastCodePoint() const; + + UChar32 codePointAt(int32_t index) const; + + UChar32 codePointBefore(int32_t index) const; + + FormattedStringBuilder &clear(); + + /** Appends a UTF-16 code unit. */ + inline int32_t appendChar16(char16_t codeUnit, Field field, UErrorCode& status) { + // appendCodePoint handles both code units and code points. + return insertCodePoint(fLength, codeUnit, field, status); + } + + /** Inserts a UTF-16 code unit. Note: insert at index 0 is very efficient. */ + inline int32_t insertChar16(int32_t index, char16_t codeUnit, Field field, UErrorCode& status) { + // insertCodePoint handles both code units and code points. + return insertCodePoint(index, codeUnit, field, status); + } + + /** Appends a Unicode code point. */ + inline int32_t appendCodePoint(UChar32 codePoint, Field field, UErrorCode &status) { + return insertCodePoint(fLength, codePoint, field, status); + } + + /** Inserts a Unicode code point. Note: insert at index 0 is very efficient. */ + int32_t insertCodePoint(int32_t index, UChar32 codePoint, Field field, UErrorCode &status); + + /** Appends a string. */ + inline int32_t append(const UnicodeString &unistr, Field field, UErrorCode &status) { + return insert(fLength, unistr, field, status); + } + + /** Inserts a string. Note: insert at index 0 is very efficient. */ + int32_t insert(int32_t index, const UnicodeString &unistr, Field field, UErrorCode &status); + + /** Inserts a substring. Note: insert at index 0 is very efficient. + * + * @param start Start index of the substring of unistr to be inserted. + * @param end End index of the substring of unistr to be inserted (exclusive). + */ + int32_t insert(int32_t index, const UnicodeString &unistr, int32_t start, int32_t end, Field field, + UErrorCode &status); + + /** Deletes a substring and then inserts a string at that same position. + * Similar to JavaScript Array.prototype.splice(). + * + * @param startThis Start of the span to delete. + * @param endThis End of the span to delete (exclusive). + * @param unistr The string to insert at the deletion position. + * @param startOther Start index of the substring of unistr to be inserted. + * @param endOther End index of the substring of unistr to be inserted (exclusive). + */ + int32_t splice(int32_t startThis, int32_t endThis, const UnicodeString &unistr, + int32_t startOther, int32_t endOther, Field field, UErrorCode& status); + + /** Appends a formatted string. */ + int32_t append(const FormattedStringBuilder &other, UErrorCode &status); + + /** Inserts a formatted string. Note: insert at index 0 is very efficient. */ + int32_t insert(int32_t index, const FormattedStringBuilder &other, UErrorCode &status); + + /** + * Ensures that the string buffer contains a NUL terminator. The NUL terminator does + * not count toward the string length. Any further changes to the string (insert or + * append) may invalidate the NUL terminator. + * + * You should call this method after the formatted string is completely built if you + * plan to return a pointer to the string from a C API. + */ + void writeTerminator(UErrorCode& status); + + /** + * Gets a "safe" UnicodeString that can be used even after the FormattedStringBuilder is destructed. + */ + UnicodeString toUnicodeString() const; + + /** + * Gets an "unsafe" UnicodeString that is valid only as long as the FormattedStringBuilder is alive and + * unchanged. Slightly faster than toUnicodeString(). + */ + const UnicodeString toTempUnicodeString() const; + + UnicodeString toDebugString() const; + + const char16_t *chars() const; + + bool contentEquals(const FormattedStringBuilder &other) const; + + bool containsField(Field field) const; + + private: + bool fUsingHeap = false; + ValueOrHeapArray<char16_t> fChars; + ValueOrHeapArray<Field> fFields; + int32_t fZero = DEFAULT_CAPACITY / 2; + int32_t fLength = 0; + + inline char16_t *getCharPtr() { + return fUsingHeap ? fChars.heap.ptr : fChars.value; + } + + inline const char16_t *getCharPtr() const { + return fUsingHeap ? fChars.heap.ptr : fChars.value; + } + + inline Field *getFieldPtr() { + return fUsingHeap ? fFields.heap.ptr : fFields.value; + } + + inline const Field *getFieldPtr() const { + return fUsingHeap ? fFields.heap.ptr : fFields.value; + } + + inline int32_t getCapacity() const { + return fUsingHeap ? fChars.heap.capacity : DEFAULT_CAPACITY; + } + + int32_t prepareForInsert(int32_t index, int32_t count, UErrorCode &status); + + int32_t prepareForInsertHelper(int32_t index, int32_t count, UErrorCode &status); + + int32_t remove(int32_t index, int32_t count); + + friend class FormattedValueStringBuilderImpl; +}; + +/** + * Helper functions for dealing with the Field typedef, which stores fields + * in a compressed format. + */ +class StringBuilderFieldUtils { +public: + struct CategoryFieldPair { + int32_t category; + int32_t field; + }; + + /** Compile-time function to construct a Field from a category and a field */ + template <int32_t category, int32_t field> + static constexpr FormattedStringBuilder::Field compress() { + static_assert(category != 0, "cannot use Undefined category in FieldUtils"); + static_assert(category <= 0xf, "only 4 bits for category"); + static_assert(field <= 0xf, "only 4 bits for field"); + return static_cast<int8_t>((category << 4) | field); + } + + /** Runtime inline function to unpack the category and field from the Field */ + static inline CategoryFieldPair expand(FormattedStringBuilder::Field field) { + if (field == UNUM_FIELD_COUNT) { + return {UFIELD_CATEGORY_UNDEFINED, 0}; + } + CategoryFieldPair ret = { + (field >> 4), + (field & 0xf) + }; + if (ret.category == 0) { + ret.category = UFIELD_CATEGORY_NUMBER; + } + return ret; + } + + static inline bool isNumericField(FormattedStringBuilder::Field field) { + int8_t category = field >> 4; + return category == 0 || category == UFIELD_CATEGORY_NUMBER; + } +}; + +U_NAMESPACE_END + + +#endif //__NUMBER_STRINGBUILDER_H__ + +#endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/formattedval_impl.h b/deps/icu-small/source/i18n/formattedval_impl.h index 69ba0922ed..4ee53e4589 100644 --- a/deps/icu-small/source/i18n/formattedval_impl.h +++ b/deps/icu-small/source/i18n/formattedval_impl.h @@ -18,7 +18,7 @@ #include "fphdlimp.h" #include "util.h" #include "uvectr32.h" -#include "number_stringbuilder.h" +#include "formatted_string_builder.h" /** @@ -67,7 +67,9 @@ typedef enum UCFPosConstraintType { U_NAMESPACE_BEGIN -/** Implementation using FieldPositionHandler to accept fields. */ +/** + * Implementation of FormattedValue using FieldPositionHandler to accept fields. + */ class FormattedValueFieldPositionIteratorImpl : public UMemory, public FormattedValue { public: @@ -112,12 +114,21 @@ private: }; -class FormattedValueNumberStringBuilderImpl : public UMemory, public FormattedValue { +/** + * Implementation of FormattedValue based on FormattedStringBuilder. + * + * The implementation currently revolves around numbers and number fields. + * However, it can be generalized in the future when there is a need. + * + * @author sffc (Shane Carr) + */ +// Exported as U_I18N_API for tests +class U_I18N_API FormattedValueStringBuilderImpl : public UMemory, public FormattedValue { public: - FormattedValueNumberStringBuilderImpl(number::impl::Field numericField); + FormattedValueStringBuilderImpl(FormattedStringBuilder::Field numericField); - virtual ~FormattedValueNumberStringBuilderImpl(); + virtual ~FormattedValueStringBuilderImpl(); // Implementation of FormattedValue (const): @@ -126,17 +137,25 @@ public: Appendable& appendTo(Appendable& appendable, UErrorCode& status) const U_OVERRIDE; UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE; - inline number::impl::NumberStringBuilder& getStringRef() { + // Additional helper functions: + UBool nextFieldPosition(FieldPosition& fp, UErrorCode& status) const; + void getAllFieldPositions(FieldPositionIteratorHandler& fpih, UErrorCode& status) const; + inline FormattedStringBuilder& getStringRef() { return fString; } - - inline const number::impl::NumberStringBuilder& getStringRef() const { + inline const FormattedStringBuilder& getStringRef() const { return fString; } private: - number::impl::NumberStringBuilder fString; - number::impl::Field fNumericField; + FormattedStringBuilder fString; + FormattedStringBuilder::Field fNumericField; + + bool nextPositionImpl(ConstrainedFieldPosition& cfpos, FormattedStringBuilder::Field numericField, UErrorCode& status) const; + static bool isIntOrGroup(FormattedStringBuilder::Field field); + static bool isNumericField(FormattedStringBuilder::Field field); + int32_t trimBack(int32_t limit) const; + int32_t trimFront(int32_t start) const; }; diff --git a/deps/icu-small/source/i18n/formattedval_sbimpl.cpp b/deps/icu-small/source/i18n/formattedval_sbimpl.cpp index 1fbecf25ac..ca28f22281 100644 --- a/deps/icu-small/source/i18n/formattedval_sbimpl.cpp +++ b/deps/icu-small/source/i18n/formattedval_sbimpl.cpp @@ -9,35 +9,203 @@ // Other independent implementations should go into their own cpp file for // better dependency modularization. +#include "unicode/ustring.h" #include "formattedval_impl.h" +#include "number_types.h" +#include "formatted_string_builder.h" +#include "number_utils.h" +#include "static_unicode_sets.h" U_NAMESPACE_BEGIN -FormattedValueNumberStringBuilderImpl::FormattedValueNumberStringBuilderImpl(number::impl::Field numericField) +typedef FormattedStringBuilder::Field Field; + + +FormattedValueStringBuilderImpl::FormattedValueStringBuilderImpl(Field numericField) : fNumericField(numericField) { } -FormattedValueNumberStringBuilderImpl::~FormattedValueNumberStringBuilderImpl() { +FormattedValueStringBuilderImpl::~FormattedValueStringBuilderImpl() { } -UnicodeString FormattedValueNumberStringBuilderImpl::toString(UErrorCode&) const { +UnicodeString FormattedValueStringBuilderImpl::toString(UErrorCode&) const { return fString.toUnicodeString(); } -UnicodeString FormattedValueNumberStringBuilderImpl::toTempString(UErrorCode&) const { +UnicodeString FormattedValueStringBuilderImpl::toTempString(UErrorCode&) const { return fString.toTempUnicodeString(); } -Appendable& FormattedValueNumberStringBuilderImpl::appendTo(Appendable& appendable, UErrorCode&) const { +Appendable& FormattedValueStringBuilderImpl::appendTo(Appendable& appendable, UErrorCode&) const { appendable.appendString(fString.chars(), fString.length()); return appendable; } -UBool FormattedValueNumberStringBuilderImpl::nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const { +UBool FormattedValueStringBuilderImpl::nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const { // NOTE: MSVC sometimes complains when implicitly converting between bool and UBool - return fString.nextPosition(cfpos, fNumericField, status) ? TRUE : FALSE; + return nextPositionImpl(cfpos, fNumericField, status) ? TRUE : FALSE; +} + +UBool FormattedValueStringBuilderImpl::nextFieldPosition(FieldPosition& fp, UErrorCode& status) const { + int32_t rawField = fp.getField(); + + if (rawField == FieldPosition::DONT_CARE) { + return FALSE; + } + + if (rawField < 0 || rawField >= UNUM_FIELD_COUNT) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return FALSE; + } + + ConstrainedFieldPosition cfpos; + cfpos.constrainField(UFIELD_CATEGORY_NUMBER, rawField); + cfpos.setState(UFIELD_CATEGORY_NUMBER, rawField, fp.getBeginIndex(), fp.getEndIndex()); + if (nextPositionImpl(cfpos, 0, status)) { + fp.setBeginIndex(cfpos.getStart()); + fp.setEndIndex(cfpos.getLimit()); + return TRUE; + } + + // Special case: fraction should start after integer if fraction is not present + if (rawField == UNUM_FRACTION_FIELD && fp.getEndIndex() == 0) { + bool inside = false; + int32_t i = fString.fZero; + for (; i < fString.fZero + fString.fLength; i++) { + if (isIntOrGroup(fString.getFieldPtr()[i]) || fString.getFieldPtr()[i] == UNUM_DECIMAL_SEPARATOR_FIELD) { + inside = true; + } else if (inside) { + break; + } + } + fp.setBeginIndex(i - fString.fZero); + fp.setEndIndex(i - fString.fZero); + } + + return FALSE; +} + +void FormattedValueStringBuilderImpl::getAllFieldPositions(FieldPositionIteratorHandler& fpih, + UErrorCode& status) const { + ConstrainedFieldPosition cfpos; + while (nextPositionImpl(cfpos, 0, status)) { + fpih.addAttribute(cfpos.getField(), cfpos.getStart(), cfpos.getLimit()); + } +} + +// Signal the end of the string using a field that doesn't exist and that is +// different from UNUM_FIELD_COUNT, which is used for "null number field". +static constexpr Field kEndField = 0xff; + +bool FormattedValueStringBuilderImpl::nextPositionImpl(ConstrainedFieldPosition& cfpos, Field numericField, UErrorCode& /*status*/) const { + auto numericCAF = StringBuilderFieldUtils::expand(numericField); + int32_t fieldStart = -1; + Field currField = UNUM_FIELD_COUNT; + for (int32_t i = fString.fZero + cfpos.getLimit(); i <= fString.fZero + fString.fLength; i++) { + Field _field = (i < fString.fZero + fString.fLength) ? fString.getFieldPtr()[i] : kEndField; + // Case 1: currently scanning a field. + if (currField != UNUM_FIELD_COUNT) { + if (currField != _field) { + int32_t end = i - fString.fZero; + // Grouping separators can be whitespace; don't throw them out! + if (currField != UNUM_GROUPING_SEPARATOR_FIELD) { + end = trimBack(i - fString.fZero); + } + if (end <= fieldStart) { + // Entire field position is ignorable; skip. + fieldStart = -1; + currField = UNUM_FIELD_COUNT; + i--; // look at this index again + continue; + } + int32_t start = fieldStart; + if (currField != UNUM_GROUPING_SEPARATOR_FIELD) { + start = trimFront(start); + } + auto caf = StringBuilderFieldUtils::expand(currField); + cfpos.setState(caf.category, caf.field, start, end); + return true; + } + continue; + } + // Special case: coalesce the INTEGER if we are pointing at the end of the INTEGER. + if (cfpos.matchesField(UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD) + && i > fString.fZero + // don't return the same field twice in a row: + && i - fString.fZero > cfpos.getLimit() + && isIntOrGroup(fString.getFieldPtr()[i - 1]) + && !isIntOrGroup(_field)) { + int j = i - 1; + for (; j >= fString.fZero && isIntOrGroup(fString.getFieldPtr()[j]); j--) {} + cfpos.setState( + UFIELD_CATEGORY_NUMBER, + UNUM_INTEGER_FIELD, + j - fString.fZero + 1, + i - fString.fZero); + return true; + } + // Special case: coalesce NUMERIC if we are pointing at the end of the NUMERIC. + if (numericField != 0 + && cfpos.matchesField(numericCAF.category, numericCAF.field) + && i > fString.fZero + // don't return the same field twice in a row: + && (i - fString.fZero > cfpos.getLimit() + || cfpos.getCategory() != numericCAF.category + || cfpos.getField() != numericCAF.field) + && isNumericField(fString.getFieldPtr()[i - 1]) + && !isNumericField(_field)) { + int j = i - 1; + for (; j >= fString.fZero && isNumericField(fString.getFieldPtr()[j]); j--) {} + cfpos.setState( + numericCAF.category, + numericCAF.field, + j - fString.fZero + 1, + i - fString.fZero); + return true; + } + // Special case: skip over INTEGER; will be coalesced later. + if (_field == UNUM_INTEGER_FIELD) { + _field = UNUM_FIELD_COUNT; + } + // Case 2: no field starting at this position. + if (_field == UNUM_FIELD_COUNT || _field == kEndField) { + continue; + } + // Case 3: check for field starting at this position + auto caf = StringBuilderFieldUtils::expand(_field); + if (cfpos.matchesField(caf.category, caf.field)) { + fieldStart = i - fString.fZero; + currField = _field; + } + } + + U_ASSERT(currField == UNUM_FIELD_COUNT); + return false; +} + +bool FormattedValueStringBuilderImpl::isIntOrGroup(Field field) { + return field == UNUM_INTEGER_FIELD + || field == UNUM_GROUPING_SEPARATOR_FIELD; +} + +bool FormattedValueStringBuilderImpl::isNumericField(Field field) { + return StringBuilderFieldUtils::isNumericField(field); +} + +int32_t FormattedValueStringBuilderImpl::trimBack(int32_t limit) const { + return unisets::get(unisets::DEFAULT_IGNORABLES)->spanBack( + fString.getCharPtr() + fString.fZero, + limit, + USET_SPAN_CONTAINED); +} + +int32_t FormattedValueStringBuilderImpl::trimFront(int32_t start) const { + return start + unisets::get(unisets::DEFAULT_IGNORABLES)->span( + fString.getCharPtr() + fString.fZero + start, + fString.fLength - start, + USET_SPAN_CONTAINED); } diff --git a/deps/icu-small/source/i18n/funcrepl.cpp b/deps/icu-small/source/i18n/funcrepl.cpp index 30bcebbf90..ceb456e1af 100644 --- a/deps/icu-small/source/i18n/funcrepl.cpp +++ b/deps/icu-small/source/i18n/funcrepl.cpp @@ -59,7 +59,7 @@ FunctionReplacer::~FunctionReplacer() { /** * Implement UnicodeFunctor */ -UnicodeFunctor* FunctionReplacer::clone() const { +FunctionReplacer* FunctionReplacer::clone() const { return new FunctionReplacer(*this); } diff --git a/deps/icu-small/source/i18n/funcrepl.h b/deps/icu-small/source/i18n/funcrepl.h index a835d5be7c..fe41f6caaa 100644 --- a/deps/icu-small/source/i18n/funcrepl.h +++ b/deps/icu-small/source/i18n/funcrepl.h @@ -70,7 +70,7 @@ class FunctionReplacer : public UnicodeFunctor, public UnicodeReplacer { /** * Implement UnicodeFunctor */ - virtual UnicodeFunctor* clone() const; + virtual FunctionReplacer* clone() const; /** * UnicodeFunctor API. Cast 'this' to a UnicodeReplacer* pointer diff --git a/deps/icu-small/source/i18n/gender.cpp b/deps/icu-small/source/i18n/gender.cpp index 106cf424c5..03c03cecad 100644 --- a/deps/icu-small/source/i18n/gender.cpp +++ b/deps/icu-small/source/i18n/gender.cpp @@ -98,7 +98,7 @@ const GenderInfo* GenderInfo::getInstance(const Locale& locale, UErrorCode& stat return NULL; } - static UMutex gGenderMetaLock = U_MUTEX_INITIALIZER; + static UMutex gGenderMetaLock; const GenderInfo* result = NULL; const char* key = locale.getName(); { diff --git a/deps/icu-small/source/i18n/gregocal.cpp b/deps/icu-small/source/i18n/gregocal.cpp index 4db66758df..028ab05aa9 100644 --- a/deps/icu-small/source/i18n/gregocal.cpp +++ b/deps/icu-small/source/i18n/gregocal.cpp @@ -286,7 +286,7 @@ fIsGregorian(source.fIsGregorian), fInvertGregorian(source.fInvertGregorian) // ------------------------------------- -Calendar* GregorianCalendar::clone() const +GregorianCalendar* GregorianCalendar::clone() const { return new GregorianCalendar(*this); } @@ -324,26 +324,26 @@ GregorianCalendar::setGregorianChange(UDate date, UErrorCode& status) if (U_FAILURE(status)) return; - fGregorianCutover = date; - // Precompute two internal variables which we use to do the actual // cutover computations. These are the normalized cutover, which is the // midnight at or before the cutover, and the cutover year. The // normalized cutover is in pure date milliseconds; it contains no time // of day or timezone component, and it used to compare against other // pure date values. - int32_t cutoverDay = (int32_t)ClockMath::floorDivide(fGregorianCutover, (double)kOneDay); - fNormalizedGregorianCutover = cutoverDay * kOneDay; - - // Handle the rare case of numeric overflow. If the user specifies a - // change of UDate(Long.MIN_VALUE), in order to get a pure Gregorian - // calendar, then the epoch day is -106751991168, which when multiplied - // by ONE_DAY gives 9223372036794351616 -- the negative value is too - // large for 64 bits, and overflows into a positive value. We correct - // this by using the next day, which for all intents is semantically - // equivalent. - if (cutoverDay < 0 && fNormalizedGregorianCutover > 0) { - fNormalizedGregorianCutover = (cutoverDay + 1) * kOneDay; + double cutoverDay = ClockMath::floorDivide(date, (double)kOneDay); + + // Handle the rare case of numeric overflow where the user specifies a time + // outside of INT32_MIN .. INT32_MAX number of days. + + if (cutoverDay <= INT32_MIN) { + cutoverDay = INT32_MIN; + fGregorianCutover = fNormalizedGregorianCutover = cutoverDay * kOneDay; + } else if (cutoverDay >= INT32_MAX) { + cutoverDay = INT32_MAX; + fGregorianCutover = fNormalizedGregorianCutover = cutoverDay * kOneDay; + } else { + fNormalizedGregorianCutover = cutoverDay * kOneDay; + fGregorianCutover = date; } // Normalize the year so BC values are represented as 0 and negative @@ -360,7 +360,7 @@ GregorianCalendar::setGregorianChange(UDate date, UErrorCode& status) fGregorianCutoverYear = cal->get(UCAL_YEAR, status); if (cal->get(UCAL_ERA, status) == BC) fGregorianCutoverYear = 1 - fGregorianCutoverYear; - fCutoverJulianDay = cutoverDay; + fCutoverJulianDay = (int32_t)cutoverDay; delete cal; } diff --git a/deps/icu-small/source/i18n/hebrwcal.cpp b/deps/icu-small/source/i18n/hebrwcal.cpp index 66a3e47a4f..085ded7846 100644 --- a/deps/icu-small/source/i18n/hebrwcal.cpp +++ b/deps/icu-small/source/i18n/hebrwcal.cpp @@ -169,7 +169,7 @@ const char *HebrewCalendar::getType() const { return "hebrew"; } -Calendar* HebrewCalendar::clone() const { +HebrewCalendar* HebrewCalendar::clone() const { return new HebrewCalendar(*this); } diff --git a/deps/icu-small/source/i18n/hebrwcal.h b/deps/icu-small/source/i18n/hebrwcal.h index 9323ad62aa..97e8511705 100644 --- a/deps/icu-small/source/i18n/hebrwcal.h +++ b/deps/icu-small/source/i18n/hebrwcal.h @@ -192,7 +192,7 @@ public: * @return return a polymorphic copy of this calendar. * @internal */ - virtual Calendar* clone(void) const; + virtual HebrewCalendar* clone() const; public: /** diff --git a/deps/icu-small/source/i18n/indiancal.cpp b/deps/icu-small/source/i18n/indiancal.cpp index 667b6f2d7a..f1266bb775 100644 --- a/deps/icu-small/source/i18n/indiancal.cpp +++ b/deps/icu-small/source/i18n/indiancal.cpp @@ -35,7 +35,7 @@ U_NAMESPACE_BEGIN //------------------------------------------------------------------------- -Calendar* IndianCalendar::clone() const { +IndianCalendar* IndianCalendar::clone() const { return new IndianCalendar(*this); } diff --git a/deps/icu-small/source/i18n/indiancal.h b/deps/icu-small/source/i18n/indiancal.h index ffd4ae8b8a..142597ce0e 100644 --- a/deps/icu-small/source/i18n/indiancal.h +++ b/deps/icu-small/source/i18n/indiancal.h @@ -186,7 +186,7 @@ public: // TODO: copy c'tor, etc // clone - virtual Calendar* clone() const; + virtual IndianCalendar* clone() const; private: /** diff --git a/deps/icu-small/source/i18n/islamcal.cpp b/deps/icu-small/source/i18n/islamcal.cpp index 8d6171af01..4e4a664804 100644 --- a/deps/icu-small/source/i18n/islamcal.cpp +++ b/deps/icu-small/source/i18n/islamcal.cpp @@ -227,7 +227,7 @@ const char *IslamicCalendar::getType() const { return sType; } -Calendar* IslamicCalendar::clone() const { +IslamicCalendar* IslamicCalendar::clone() const { return new IslamicCalendar(*this); } @@ -470,7 +470,7 @@ double IslamicCalendar::moonAge(UDate time, UErrorCode &status) { double age = 0; - static UMutex astroLock = U_MUTEX_INITIALIZER; // pod bay door lock + static UMutex astroLock; // pod bay door lock umtx_lock(&astroLock); if(gIslamicCalendarAstro == NULL) { gIslamicCalendarAstro = new CalendarAstronomer(); diff --git a/deps/icu-small/source/i18n/islamcal.h b/deps/icu-small/source/i18n/islamcal.h index 17fb6687ef..aad8f07be0 100644 --- a/deps/icu-small/source/i18n/islamcal.h +++ b/deps/icu-small/source/i18n/islamcal.h @@ -230,7 +230,7 @@ class U_I18N_API IslamicCalendar : public Calendar { // TODO: copy c'tor, etc // clone - virtual Calendar* clone() const; + virtual IslamicCalendar* clone() const; private: /** diff --git a/deps/icu-small/source/i18n/japancal.cpp b/deps/icu-small/source/i18n/japancal.cpp index cc061fd141..e7e5f4fc51 100644 --- a/deps/icu-small/source/i18n/japancal.cpp +++ b/deps/icu-small/source/i18n/japancal.cpp @@ -136,7 +136,7 @@ JapaneseCalendar& JapaneseCalendar::operator= ( const JapaneseCalendar& right) return *this; } -Calendar* JapaneseCalendar::clone(void) const +JapaneseCalendar* JapaneseCalendar::clone() const { return new JapaneseCalendar(*this); } diff --git a/deps/icu-small/source/i18n/japancal.h b/deps/icu-small/source/i18n/japancal.h index a32f3db563..ee86c4ed0e 100644 --- a/deps/icu-small/source/i18n/japancal.h +++ b/deps/icu-small/source/i18n/japancal.h @@ -116,7 +116,7 @@ public: * @return return a polymorphic copy of this calendar. * @internal */ - virtual Calendar* clone(void) const; + virtual JapaneseCalendar* clone() const; /** * Return the extended year defined by the current fields. In the diff --git a/deps/icu-small/source/i18n/listformatter.cpp b/deps/icu-small/source/i18n/listformatter.cpp index 64d2e36ae1..35cc00de25 100644 --- a/deps/icu-small/source/i18n/listformatter.cpp +++ b/deps/icu-small/source/i18n/listformatter.cpp @@ -144,7 +144,7 @@ const ListFormatInternal* ListFormatter::getListFormatInternal( keyBuffer.append(':', errorCode).append(style, errorCode); UnicodeString key(keyBuffer.data(), -1, US_INV); ListFormatInternal* result = nullptr; - static UMutex listFormatterMutex = U_MUTEX_INITIALIZER; + static UMutex listFormatterMutex; { Mutex m(&listFormatterMutex); if (listPatternHash == nullptr) { @@ -478,8 +478,8 @@ UnicodeString& ListFormatter::format_( if (index == 0) { offset = 0; } - int32_t offsetFirst; - int32_t offsetSecond; + int32_t offsetFirst = 0; + int32_t offsetSecond = 0; int32_t prefixLength = 0; // for n items, there are 2 * (n + 1) boundary including 0 and the upper // edge. diff --git a/deps/icu-small/source/i18n/measfmt.cpp b/deps/icu-small/source/i18n/measfmt.cpp index 03e4417e64..47ffb140cf 100644 --- a/deps/icu-small/source/i18n/measfmt.cpp +++ b/deps/icu-small/source/i18n/measfmt.cpp @@ -55,28 +55,23 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(MeasureFormat) class NumericDateFormatters : public UMemory { public: // Formats like H:mm - SimpleDateFormat hourMinute; + UnicodeString hourMinute; // formats like M:ss - SimpleDateFormat minuteSecond; + UnicodeString minuteSecond; // formats like H:mm:ss - SimpleDateFormat hourMinuteSecond; + UnicodeString hourMinuteSecond; // Constructor that takes the actual patterns for hour-minute, // minute-second, and hour-minute-second respectively. NumericDateFormatters( const UnicodeString &hm, const UnicodeString &ms, - const UnicodeString &hms, - UErrorCode &status) : - hourMinute(hm, status), - minuteSecond(ms, status), - hourMinuteSecond(hms, status) { - const TimeZone *gmt = TimeZone::getGMT(); - hourMinute.setTimeZone(*gmt); - minuteSecond.setTimeZone(*gmt); - hourMinuteSecond.setTimeZone(*gmt); + const UnicodeString &hms) : + hourMinute(hm), + minuteSecond(ms), + hourMinuteSecond(hms) { } private: NumericDateFormatters(const NumericDateFormatters &other); @@ -233,8 +228,7 @@ static NumericDateFormatters *loadNumericDateFormatters( NumericDateFormatters *result = new NumericDateFormatters( loadNumericDateFormatterPattern(resource, "hm", status), loadNumericDateFormatterPattern(resource, "ms", status), - loadNumericDateFormatterPattern(resource, "hms", status), - status); + loadNumericDateFormatterPattern(resource, "hms", status)); if (U_FAILURE(status)) { delete result; return NULL; @@ -466,7 +460,7 @@ UBool MeasureFormat::operator==(const Format &other) const { **numberFormat == **rhs.numberFormat); } -Format *MeasureFormat::clone() const { +MeasureFormat *MeasureFormat::clone() const { return new MeasureFormat(*this); } @@ -691,9 +685,19 @@ UnicodeString &MeasureFormat::formatMeasure( } auto* df = dynamic_cast<const DecimalFormat*>(&nf); if (df == nullptr) { - // Don't know how to handle other types of NumberFormat - status = U_UNSUPPORTED_ERROR; - return appendTo; + // Handle other types of NumberFormat using the ICU 63 code, modified to + // get the unitPattern from LongNameHandler and handle fallback to OTHER. + UnicodeString formattedNumber; + StandardPlural::Form pluralForm = QuantityFormatter::selectPlural( + amtNumber, nf, **pluralRules, formattedNumber, pos, status); + UnicodeString pattern = number::impl::LongNameHandler::getUnitPattern(getLocale(status), + amtUnit, getUnitWidth(fWidth), pluralForm, status); + // The above handles fallback from other widths to short, and from other plural forms to OTHER + if (U_FAILURE(status)) { + return appendTo; + } + SimpleFormatter formatter(pattern, 0, 1, status); + return QuantityFormatter::format(formatter, formattedNumber, appendTo, pos, status); } number::FormattedNumber result; if (auto* lnf = df->toNumberFormatter(status)) { @@ -706,135 +710,112 @@ UnicodeString &MeasureFormat::formatMeasure( return appendTo; } -// Formats hours-minutes-seconds as 5:37:23 or similar. + +// Formats numeric time duration as 5:00:47 or 3:54. UnicodeString &MeasureFormat::formatNumeric( const Formattable *hms, // always length 3 - int32_t bitMap, // 1=hourset, 2=minuteset, 4=secondset + int32_t bitMap, // 1=hour set, 2=minute set, 4=second set UnicodeString &appendTo, UErrorCode &status) const { if (U_FAILURE(status)) { return appendTo; } - UDate millis = - (UDate) (((uprv_trunc(hms[0].getDouble(status)) * 60.0 - + uprv_trunc(hms[1].getDouble(status))) * 60.0 - + uprv_trunc(hms[2].getDouble(status))) * 1000.0); - switch (bitMap) { - case 5: // hs - case 7: // hms - return formatNumeric( - millis, - cache->getNumericDateFormatters()->hourMinuteSecond, - UDAT_SECOND_FIELD, - hms[2], - appendTo, - status); - break; - case 6: // ms - return formatNumeric( - millis, - cache->getNumericDateFormatters()->minuteSecond, - UDAT_SECOND_FIELD, - hms[2], - appendTo, - status); - break; - case 3: // hm - return formatNumeric( - millis, - cache->getNumericDateFormatters()->hourMinute, - UDAT_MINUTE_FIELD, - hms[1], - appendTo, - status); - break; - default: - status = U_INTERNAL_PROGRAM_ERROR; - return appendTo; - break; - } -} - -static void appendRange( - const UnicodeString &src, - int32_t start, - int32_t end, - UnicodeString &dest) { - dest.append(src, start, end - start); -} -static void appendRange( - const UnicodeString &src, - int32_t end, - UnicodeString &dest) { - dest.append(src, end, src.length() - end); -} + UnicodeString pattern; -// Formats time like 5:37:23 -UnicodeString &MeasureFormat::formatNumeric( - UDate date, // Time since epoch 1:30:00 would be 5400000 - const DateFormat &dateFmt, // h:mm, m:ss, or h:mm:ss - UDateFormatField smallestField, // seconds in 5:37:23.5 - const Formattable &smallestAmount, // 23.5 for 5:37:23.5 - UnicodeString &appendTo, - UErrorCode &status) const { + double hours = hms[0].getDouble(status); + double minutes = hms[1].getDouble(status); + double seconds = hms[2].getDouble(status); if (U_FAILURE(status)) { return appendTo; } - // Format the smallest amount with this object's NumberFormat - UnicodeString smallestAmountFormatted; - - // We keep track of the integer part of smallest amount so that - // we can replace it later so that we get '0:00:09.3' instead of - // '0:00:9.3' - FieldPosition intFieldPosition(UNUM_INTEGER_FIELD); - (*numberFormat)->format( - smallestAmount, smallestAmountFormatted, intFieldPosition, status); - if ( - intFieldPosition.getBeginIndex() == 0 && - intFieldPosition.getEndIndex() == 0) { + + // All possible combinations: "h", "m", "s", "hm", "hs", "ms", "hms" + if (bitMap == 5 || bitMap == 7) { // "hms" & "hs" (we add minutes if "hs") + pattern = cache->getNumericDateFormatters()->hourMinuteSecond; + hours = uprv_trunc(hours); + minutes = uprv_trunc(minutes); + } else if (bitMap == 3) { // "hm" + pattern = cache->getNumericDateFormatters()->hourMinute; + hours = uprv_trunc(hours); + } else if (bitMap == 6) { // "ms" + pattern = cache->getNumericDateFormatters()->minuteSecond; + minutes = uprv_trunc(minutes); + } else { // h m s, handled outside formatNumeric. No value is also an error. status = U_INTERNAL_PROGRAM_ERROR; return appendTo; } - // Format time. draft becomes something like '5:30:45' - // #13606: DateFormat is not thread-safe, but MeasureFormat advertises itself as thread-safe. - FieldPosition smallestFieldPosition(smallestField); - UnicodeString draft; - static UMutex dateFmtMutex = U_MUTEX_INITIALIZER; - umtx_lock(&dateFmtMutex); - dateFmt.format(date, draft, smallestFieldPosition, status); - umtx_unlock(&dateFmtMutex); - - // If we find field for smallest amount replace it with the formatted - // smallest amount from above taking care to replace the integer part - // with what is in original time. For example, If smallest amount - // is 9.35s and the formatted time is 0:00:09 then 9.35 becomes 09.35 - // and replacing yields 0:00:09.35 - if (smallestFieldPosition.getBeginIndex() != 0 || - smallestFieldPosition.getEndIndex() != 0) { - appendRange(draft, 0, smallestFieldPosition.getBeginIndex(), appendTo); - appendRange( - smallestAmountFormatted, - 0, - intFieldPosition.getBeginIndex(), - appendTo); - appendRange( - draft, - smallestFieldPosition.getBeginIndex(), - smallestFieldPosition.getEndIndex(), - appendTo); - appendRange( - smallestAmountFormatted, - intFieldPosition.getEndIndex(), - appendTo); - appendRange( - draft, - smallestFieldPosition.getEndIndex(), - appendTo); + const DecimalFormat *numberFormatter = dynamic_cast<const DecimalFormat*>(numberFormat->get()); + if (!numberFormatter) { + status = U_INTERNAL_PROGRAM_ERROR; + return appendTo; + } + number::LocalizedNumberFormatter numberFormatter2; + if (auto* lnf = numberFormatter->toNumberFormatter(status)) { + numberFormatter2 = lnf->integerWidth(number::IntegerWidth::zeroFillTo(2)); } else { - appendTo.append(draft); + return appendTo; } + + FormattedStringBuilder fsb; + + UBool protect = FALSE; + const int32_t patternLength = pattern.length(); + for (int32_t i = 0; i < patternLength; i++) { + char16_t c = pattern[i]; + + // Also set the proper field in this switch + // We don't use DateFormat.Field because this is not a date / time, is a duration. + double value = 0; + switch (c) { + case u'H': value = hours; break; + case u'm': value = minutes; break; + case u's': value = seconds; break; + } + + // For undefined field we use UNUM_FIELD_COUNT, for historical reasons. + // See cleanup bug: https://unicode-org.atlassian.net/browse/ICU-20665 + // But we give it a clear name, to keep "the ugly part" in one place. + constexpr UNumberFormatFields undefinedField = UNUM_FIELD_COUNT; + + // There is not enough info to add Field(s) for the unit because all we have are plain + // text patterns. For example in "21:51" there is no text for something like "hour", + // while in something like "21h51" there is ("h"). But we can't really tell... + switch (c) { + case u'H': + case u'm': + case u's': + if (protect) { + fsb.appendChar16(c, undefinedField, status); + } else { + UnicodeString tmp; + if ((i + 1 < patternLength) && pattern[i + 1] == c) { // doubled + tmp = numberFormatter2.formatDouble(value, status).toString(status); + i++; + } else { + numberFormatter->format(value, tmp, status); + } + // TODO: Use proper Field + fsb.append(tmp, undefinedField, status); + } + break; + case u'\'': + // '' is escaped apostrophe + if ((i + 1 < patternLength) && pattern[i + 1] == c) { + fsb.appendChar16(c, undefinedField, status); + i++; + } else { + protect = !protect; + } + break; + default: + fsb.appendChar16(c, undefinedField, status); + } + } + + appendTo.append(fsb.toTempUnicodeString()); + return appendTo; } diff --git a/deps/icu-small/source/i18n/measunit.cpp b/deps/icu-small/source/i18n/measunit.cpp index 428283e6dd..917c0cdfad 100644 --- a/deps/icu-small/source/i18n/measunit.cpp +++ b/deps/icu-small/source/i18n/measunit.cpp @@ -43,21 +43,22 @@ static const int32_t gOffsets[] = { 29, 328, 339, - 354, - 358, - 366, + 355, + 359, 368, - 372, - 393, - 395, - 409, - 412, + 370, + 374, + 381, + 402, + 404, 418, - 426, - 430, - 434, - 436, - 463 + 421, + 427, + 437, + 441, + 445, + 447, + 474 }; static const int32_t gIndexes[] = { @@ -69,21 +70,22 @@ static const int32_t gIndexes[] = { 29, 29, 40, - 55, - 59, - 67, + 56, + 60, 69, - 73, - 94, - 96, - 110, - 113, + 71, + 75, + 82, + 103, + 105, 119, - 127, - 131, - 135, - 137, - 164 + 122, + 128, + 138, + 142, + 146, + 148, + 175 }; // Must be sorted alphabetically. @@ -100,6 +102,7 @@ static const char * const gTypes[] = { "energy", "force", "frequency", + "graphics", "length", "light", "mass", @@ -456,6 +459,7 @@ static const char * const gSubTypes[] = { "century", "day", "day-person", + "decade", "hour", "microsecond", "millisecond", @@ -480,12 +484,20 @@ static const char * const gSubTypes[] = { "kilocalorie", "kilojoule", "kilowatt-hour", + "therm-us", "newton", "pound-force", "gigahertz", "hertz", "kilohertz", "megahertz", + "dot-per-centimeter", + "dot-per-inch", + "em", + "megapixel", + "pixel", + "pixel-per-centimeter", + "pixel-per-inch", "astronomical-unit", "centimeter", "decimeter", @@ -533,12 +545,14 @@ static const char * const gSubTypes[] = { "milliwatt", "watt", "atmosphere", + "bar", "hectopascal", "inch-hg", "kilopascal", "megapascal", "millibar", "millimeter-of-mercury", + "pascal", "pound-per-square-inch", "kilometer-per-hour", "knot", @@ -581,18 +595,20 @@ static const char * const gSubTypes[] = { // Must be sorted by first value and then second value. static int32_t unitPerUnitToSingleUnit[][4] = { - {379, 342, 18, 0}, - {381, 349, 18, 2}, - {383, 342, 18, 3}, - {383, 452, 4, 2}, - {383, 453, 4, 3}, - {402, 449, 3, 1}, - {405, 12, 17, 7}, - {455, 379, 4, 1} + {378, 382, 12, 5}, + {378, 387, 12, 6}, + {388, 343, 19, 0}, + {390, 350, 19, 2}, + {392, 343, 19, 3}, + {392, 463, 4, 2}, + {392, 464, 4, 3}, + {411, 460, 3, 1}, + {414, 12, 18, 9}, + {466, 388, 4, 1} }; // Shortcuts to the base unit in order to make the default constructor fast -static const int32_t kBaseTypeIdx = 15; +static const int32_t kBaseTypeIdx = 16; static const int32_t kBaseSubTypeIdx = 0; MeasureUnit *MeasureUnit::createGForce(UErrorCode &status) { @@ -939,102 +955,110 @@ MeasureUnit MeasureUnit::getDayPerson() { return MeasureUnit(7, 2); } -MeasureUnit *MeasureUnit::createHour(UErrorCode &status) { +MeasureUnit *MeasureUnit::createDecade(UErrorCode &status) { return MeasureUnit::create(7, 3, status); } -MeasureUnit MeasureUnit::getHour() { +MeasureUnit MeasureUnit::getDecade() { return MeasureUnit(7, 3); } -MeasureUnit *MeasureUnit::createMicrosecond(UErrorCode &status) { +MeasureUnit *MeasureUnit::createHour(UErrorCode &status) { return MeasureUnit::create(7, 4, status); } -MeasureUnit MeasureUnit::getMicrosecond() { +MeasureUnit MeasureUnit::getHour() { return MeasureUnit(7, 4); } -MeasureUnit *MeasureUnit::createMillisecond(UErrorCode &status) { +MeasureUnit *MeasureUnit::createMicrosecond(UErrorCode &status) { return MeasureUnit::create(7, 5, status); } -MeasureUnit MeasureUnit::getMillisecond() { +MeasureUnit MeasureUnit::getMicrosecond() { return MeasureUnit(7, 5); } -MeasureUnit *MeasureUnit::createMinute(UErrorCode &status) { +MeasureUnit *MeasureUnit::createMillisecond(UErrorCode &status) { return MeasureUnit::create(7, 6, status); } -MeasureUnit MeasureUnit::getMinute() { +MeasureUnit MeasureUnit::getMillisecond() { return MeasureUnit(7, 6); } -MeasureUnit *MeasureUnit::createMonth(UErrorCode &status) { +MeasureUnit *MeasureUnit::createMinute(UErrorCode &status) { return MeasureUnit::create(7, 7, status); } -MeasureUnit MeasureUnit::getMonth() { +MeasureUnit MeasureUnit::getMinute() { return MeasureUnit(7, 7); } -MeasureUnit *MeasureUnit::createMonthPerson(UErrorCode &status) { +MeasureUnit *MeasureUnit::createMonth(UErrorCode &status) { return MeasureUnit::create(7, 8, status); } -MeasureUnit MeasureUnit::getMonthPerson() { +MeasureUnit MeasureUnit::getMonth() { return MeasureUnit(7, 8); } -MeasureUnit *MeasureUnit::createNanosecond(UErrorCode &status) { +MeasureUnit *MeasureUnit::createMonthPerson(UErrorCode &status) { return MeasureUnit::create(7, 9, status); } -MeasureUnit MeasureUnit::getNanosecond() { +MeasureUnit MeasureUnit::getMonthPerson() { return MeasureUnit(7, 9); } -MeasureUnit *MeasureUnit::createSecond(UErrorCode &status) { +MeasureUnit *MeasureUnit::createNanosecond(UErrorCode &status) { return MeasureUnit::create(7, 10, status); } -MeasureUnit MeasureUnit::getSecond() { +MeasureUnit MeasureUnit::getNanosecond() { return MeasureUnit(7, 10); } -MeasureUnit *MeasureUnit::createWeek(UErrorCode &status) { +MeasureUnit *MeasureUnit::createSecond(UErrorCode &status) { return MeasureUnit::create(7, 11, status); } -MeasureUnit MeasureUnit::getWeek() { +MeasureUnit MeasureUnit::getSecond() { return MeasureUnit(7, 11); } -MeasureUnit *MeasureUnit::createWeekPerson(UErrorCode &status) { +MeasureUnit *MeasureUnit::createWeek(UErrorCode &status) { return MeasureUnit::create(7, 12, status); } -MeasureUnit MeasureUnit::getWeekPerson() { +MeasureUnit MeasureUnit::getWeek() { return MeasureUnit(7, 12); } -MeasureUnit *MeasureUnit::createYear(UErrorCode &status) { +MeasureUnit *MeasureUnit::createWeekPerson(UErrorCode &status) { return MeasureUnit::create(7, 13, status); } -MeasureUnit MeasureUnit::getYear() { +MeasureUnit MeasureUnit::getWeekPerson() { return MeasureUnit(7, 13); } -MeasureUnit *MeasureUnit::createYearPerson(UErrorCode &status) { +MeasureUnit *MeasureUnit::createYear(UErrorCode &status) { return MeasureUnit::create(7, 14, status); } -MeasureUnit MeasureUnit::getYearPerson() { +MeasureUnit MeasureUnit::getYear() { return MeasureUnit(7, 14); } +MeasureUnit *MeasureUnit::createYearPerson(UErrorCode &status) { + return MeasureUnit::create(7, 15, status); +} + +MeasureUnit MeasureUnit::getYearPerson() { + return MeasureUnit(7, 15); +} + MeasureUnit *MeasureUnit::createAmpere(UErrorCode &status) { return MeasureUnit::create(8, 0, status); } @@ -1131,6 +1155,14 @@ MeasureUnit MeasureUnit::getKilowattHour() { return MeasureUnit(9, 7); } +MeasureUnit *MeasureUnit::createThermUs(UErrorCode &status) { + return MeasureUnit::create(9, 8, status); +} + +MeasureUnit MeasureUnit::getThermUs() { + return MeasureUnit(9, 8); +} + MeasureUnit *MeasureUnit::createNewton(UErrorCode &status) { return MeasureUnit::create(10, 0, status); } @@ -1179,708 +1211,780 @@ MeasureUnit MeasureUnit::getMegahertz() { return MeasureUnit(11, 3); } -MeasureUnit *MeasureUnit::createAstronomicalUnit(UErrorCode &status) { +MeasureUnit *MeasureUnit::createDotPerCentimeter(UErrorCode &status) { return MeasureUnit::create(12, 0, status); } -MeasureUnit MeasureUnit::getAstronomicalUnit() { +MeasureUnit MeasureUnit::getDotPerCentimeter() { return MeasureUnit(12, 0); } -MeasureUnit *MeasureUnit::createCentimeter(UErrorCode &status) { +MeasureUnit *MeasureUnit::createDotPerInch(UErrorCode &status) { return MeasureUnit::create(12, 1, status); } -MeasureUnit MeasureUnit::getCentimeter() { +MeasureUnit MeasureUnit::getDotPerInch() { return MeasureUnit(12, 1); } -MeasureUnit *MeasureUnit::createDecimeter(UErrorCode &status) { +MeasureUnit *MeasureUnit::createEm(UErrorCode &status) { return MeasureUnit::create(12, 2, status); } -MeasureUnit MeasureUnit::getDecimeter() { +MeasureUnit MeasureUnit::getEm() { return MeasureUnit(12, 2); } -MeasureUnit *MeasureUnit::createFathom(UErrorCode &status) { +MeasureUnit *MeasureUnit::createMegapixel(UErrorCode &status) { return MeasureUnit::create(12, 3, status); } -MeasureUnit MeasureUnit::getFathom() { +MeasureUnit MeasureUnit::getMegapixel() { return MeasureUnit(12, 3); } -MeasureUnit *MeasureUnit::createFoot(UErrorCode &status) { +MeasureUnit *MeasureUnit::createPixel(UErrorCode &status) { return MeasureUnit::create(12, 4, status); } -MeasureUnit MeasureUnit::getFoot() { +MeasureUnit MeasureUnit::getPixel() { return MeasureUnit(12, 4); } -MeasureUnit *MeasureUnit::createFurlong(UErrorCode &status) { +MeasureUnit *MeasureUnit::createPixelPerCentimeter(UErrorCode &status) { return MeasureUnit::create(12, 5, status); } -MeasureUnit MeasureUnit::getFurlong() { +MeasureUnit MeasureUnit::getPixelPerCentimeter() { return MeasureUnit(12, 5); } -MeasureUnit *MeasureUnit::createInch(UErrorCode &status) { +MeasureUnit *MeasureUnit::createPixelPerInch(UErrorCode &status) { return MeasureUnit::create(12, 6, status); } -MeasureUnit MeasureUnit::getInch() { +MeasureUnit MeasureUnit::getPixelPerInch() { return MeasureUnit(12, 6); } +MeasureUnit *MeasureUnit::createAstronomicalUnit(UErrorCode &status) { + return MeasureUnit::create(13, 0, status); +} + +MeasureUnit MeasureUnit::getAstronomicalUnit() { + return MeasureUnit(13, 0); +} + +MeasureUnit *MeasureUnit::createCentimeter(UErrorCode &status) { + return MeasureUnit::create(13, 1, status); +} + +MeasureUnit MeasureUnit::getCentimeter() { + return MeasureUnit(13, 1); +} + +MeasureUnit *MeasureUnit::createDecimeter(UErrorCode &status) { + return MeasureUnit::create(13, 2, status); +} + +MeasureUnit MeasureUnit::getDecimeter() { + return MeasureUnit(13, 2); +} + +MeasureUnit *MeasureUnit::createFathom(UErrorCode &status) { + return MeasureUnit::create(13, 3, status); +} + +MeasureUnit MeasureUnit::getFathom() { + return MeasureUnit(13, 3); +} + +MeasureUnit *MeasureUnit::createFoot(UErrorCode &status) { + return MeasureUnit::create(13, 4, status); +} + +MeasureUnit MeasureUnit::getFoot() { + return MeasureUnit(13, 4); +} + +MeasureUnit *MeasureUnit::createFurlong(UErrorCode &status) { + return MeasureUnit::create(13, 5, status); +} + +MeasureUnit MeasureUnit::getFurlong() { + return MeasureUnit(13, 5); +} + +MeasureUnit *MeasureUnit::createInch(UErrorCode &status) { + return MeasureUnit::create(13, 6, status); +} + +MeasureUnit MeasureUnit::getInch() { + return MeasureUnit(13, 6); +} + MeasureUnit *MeasureUnit::createKilometer(UErrorCode &status) { - return MeasureUnit::create(12, 7, status); + return MeasureUnit::create(13, 7, status); } MeasureUnit MeasureUnit::getKilometer() { - return MeasureUnit(12, 7); + return MeasureUnit(13, 7); } MeasureUnit *MeasureUnit::createLightYear(UErrorCode &status) { - return MeasureUnit::create(12, 8, status); + return MeasureUnit::create(13, 8, status); } MeasureUnit MeasureUnit::getLightYear() { - return MeasureUnit(12, 8); + return MeasureUnit(13, 8); } MeasureUnit *MeasureUnit::createMeter(UErrorCode &status) { - return MeasureUnit::create(12, 9, status); + return MeasureUnit::create(13, 9, status); } MeasureUnit MeasureUnit::getMeter() { - return MeasureUnit(12, 9); + return MeasureUnit(13, 9); } MeasureUnit *MeasureUnit::createMicrometer(UErrorCode &status) { - return MeasureUnit::create(12, 10, status); + return MeasureUnit::create(13, 10, status); } MeasureUnit MeasureUnit::getMicrometer() { - return MeasureUnit(12, 10); + return MeasureUnit(13, 10); } MeasureUnit *MeasureUnit::createMile(UErrorCode &status) { - return MeasureUnit::create(12, 11, status); + return MeasureUnit::create(13, 11, status); } MeasureUnit MeasureUnit::getMile() { - return MeasureUnit(12, 11); + return MeasureUnit(13, 11); } MeasureUnit *MeasureUnit::createMileScandinavian(UErrorCode &status) { - return MeasureUnit::create(12, 12, status); + return MeasureUnit::create(13, 12, status); } MeasureUnit MeasureUnit::getMileScandinavian() { - return MeasureUnit(12, 12); + return MeasureUnit(13, 12); } MeasureUnit *MeasureUnit::createMillimeter(UErrorCode &status) { - return MeasureUnit::create(12, 13, status); + return MeasureUnit::create(13, 13, status); } MeasureUnit MeasureUnit::getMillimeter() { - return MeasureUnit(12, 13); + return MeasureUnit(13, 13); } MeasureUnit *MeasureUnit::createNanometer(UErrorCode &status) { - return MeasureUnit::create(12, 14, status); + return MeasureUnit::create(13, 14, status); } MeasureUnit MeasureUnit::getNanometer() { - return MeasureUnit(12, 14); + return MeasureUnit(13, 14); } MeasureUnit *MeasureUnit::createNauticalMile(UErrorCode &status) { - return MeasureUnit::create(12, 15, status); + return MeasureUnit::create(13, 15, status); } MeasureUnit MeasureUnit::getNauticalMile() { - return MeasureUnit(12, 15); + return MeasureUnit(13, 15); } MeasureUnit *MeasureUnit::createParsec(UErrorCode &status) { - return MeasureUnit::create(12, 16, status); + return MeasureUnit::create(13, 16, status); } MeasureUnit MeasureUnit::getParsec() { - return MeasureUnit(12, 16); + return MeasureUnit(13, 16); } MeasureUnit *MeasureUnit::createPicometer(UErrorCode &status) { - return MeasureUnit::create(12, 17, status); + return MeasureUnit::create(13, 17, status); } MeasureUnit MeasureUnit::getPicometer() { - return MeasureUnit(12, 17); + return MeasureUnit(13, 17); } MeasureUnit *MeasureUnit::createPoint(UErrorCode &status) { - return MeasureUnit::create(12, 18, status); + return MeasureUnit::create(13, 18, status); } MeasureUnit MeasureUnit::getPoint() { - return MeasureUnit(12, 18); + return MeasureUnit(13, 18); } MeasureUnit *MeasureUnit::createSolarRadius(UErrorCode &status) { - return MeasureUnit::create(12, 19, status); + return MeasureUnit::create(13, 19, status); } MeasureUnit MeasureUnit::getSolarRadius() { - return MeasureUnit(12, 19); + return MeasureUnit(13, 19); } MeasureUnit *MeasureUnit::createYard(UErrorCode &status) { - return MeasureUnit::create(12, 20, status); + return MeasureUnit::create(13, 20, status); } MeasureUnit MeasureUnit::getYard() { - return MeasureUnit(12, 20); + return MeasureUnit(13, 20); } MeasureUnit *MeasureUnit::createLux(UErrorCode &status) { - return MeasureUnit::create(13, 0, status); + return MeasureUnit::create(14, 0, status); } MeasureUnit MeasureUnit::getLux() { - return MeasureUnit(13, 0); + return MeasureUnit(14, 0); } MeasureUnit *MeasureUnit::createSolarLuminosity(UErrorCode &status) { - return MeasureUnit::create(13, 1, status); + return MeasureUnit::create(14, 1, status); } MeasureUnit MeasureUnit::getSolarLuminosity() { - return MeasureUnit(13, 1); + return MeasureUnit(14, 1); } MeasureUnit *MeasureUnit::createCarat(UErrorCode &status) { - return MeasureUnit::create(14, 0, status); + return MeasureUnit::create(15, 0, status); } MeasureUnit MeasureUnit::getCarat() { - return MeasureUnit(14, 0); + return MeasureUnit(15, 0); } MeasureUnit *MeasureUnit::createDalton(UErrorCode &status) { - return MeasureUnit::create(14, 1, status); + return MeasureUnit::create(15, 1, status); } MeasureUnit MeasureUnit::getDalton() { - return MeasureUnit(14, 1); + return MeasureUnit(15, 1); } MeasureUnit *MeasureUnit::createEarthMass(UErrorCode &status) { - return MeasureUnit::create(14, 2, status); + return MeasureUnit::create(15, 2, status); } MeasureUnit MeasureUnit::getEarthMass() { - return MeasureUnit(14, 2); + return MeasureUnit(15, 2); } MeasureUnit *MeasureUnit::createGram(UErrorCode &status) { - return MeasureUnit::create(14, 3, status); + return MeasureUnit::create(15, 3, status); } MeasureUnit MeasureUnit::getGram() { - return MeasureUnit(14, 3); + return MeasureUnit(15, 3); } MeasureUnit *MeasureUnit::createKilogram(UErrorCode &status) { - return MeasureUnit::create(14, 4, status); + return MeasureUnit::create(15, 4, status); } MeasureUnit MeasureUnit::getKilogram() { - return MeasureUnit(14, 4); + return MeasureUnit(15, 4); } MeasureUnit *MeasureUnit::createMetricTon(UErrorCode &status) { - return MeasureUnit::create(14, 5, status); + return MeasureUnit::create(15, 5, status); } MeasureUnit MeasureUnit::getMetricTon() { - return MeasureUnit(14, 5); + return MeasureUnit(15, 5); } MeasureUnit *MeasureUnit::createMicrogram(UErrorCode &status) { - return MeasureUnit::create(14, 6, status); + return MeasureUnit::create(15, 6, status); } MeasureUnit MeasureUnit::getMicrogram() { - return MeasureUnit(14, 6); + return MeasureUnit(15, 6); } MeasureUnit *MeasureUnit::createMilligram(UErrorCode &status) { - return MeasureUnit::create(14, 7, status); + return MeasureUnit::create(15, 7, status); } MeasureUnit MeasureUnit::getMilligram() { - return MeasureUnit(14, 7); + return MeasureUnit(15, 7); } MeasureUnit *MeasureUnit::createOunce(UErrorCode &status) { - return MeasureUnit::create(14, 8, status); + return MeasureUnit::create(15, 8, status); } MeasureUnit MeasureUnit::getOunce() { - return MeasureUnit(14, 8); + return MeasureUnit(15, 8); } MeasureUnit *MeasureUnit::createOunceTroy(UErrorCode &status) { - return MeasureUnit::create(14, 9, status); + return MeasureUnit::create(15, 9, status); } MeasureUnit MeasureUnit::getOunceTroy() { - return MeasureUnit(14, 9); + return MeasureUnit(15, 9); } MeasureUnit *MeasureUnit::createPound(UErrorCode &status) { - return MeasureUnit::create(14, 10, status); + return MeasureUnit::create(15, 10, status); } MeasureUnit MeasureUnit::getPound() { - return MeasureUnit(14, 10); + return MeasureUnit(15, 10); } MeasureUnit *MeasureUnit::createSolarMass(UErrorCode &status) { - return MeasureUnit::create(14, 11, status); + return MeasureUnit::create(15, 11, status); } MeasureUnit MeasureUnit::getSolarMass() { - return MeasureUnit(14, 11); + return MeasureUnit(15, 11); } MeasureUnit *MeasureUnit::createStone(UErrorCode &status) { - return MeasureUnit::create(14, 12, status); + return MeasureUnit::create(15, 12, status); } MeasureUnit MeasureUnit::getStone() { - return MeasureUnit(14, 12); + return MeasureUnit(15, 12); } MeasureUnit *MeasureUnit::createTon(UErrorCode &status) { - return MeasureUnit::create(14, 13, status); + return MeasureUnit::create(15, 13, status); } MeasureUnit MeasureUnit::getTon() { - return MeasureUnit(14, 13); + return MeasureUnit(15, 13); } MeasureUnit *MeasureUnit::createGigawatt(UErrorCode &status) { - return MeasureUnit::create(16, 0, status); + return MeasureUnit::create(17, 0, status); } MeasureUnit MeasureUnit::getGigawatt() { - return MeasureUnit(16, 0); + return MeasureUnit(17, 0); } MeasureUnit *MeasureUnit::createHorsepower(UErrorCode &status) { - return MeasureUnit::create(16, 1, status); + return MeasureUnit::create(17, 1, status); } MeasureUnit MeasureUnit::getHorsepower() { - return MeasureUnit(16, 1); + return MeasureUnit(17, 1); } MeasureUnit *MeasureUnit::createKilowatt(UErrorCode &status) { - return MeasureUnit::create(16, 2, status); + return MeasureUnit::create(17, 2, status); } MeasureUnit MeasureUnit::getKilowatt() { - return MeasureUnit(16, 2); + return MeasureUnit(17, 2); } MeasureUnit *MeasureUnit::createMegawatt(UErrorCode &status) { - return MeasureUnit::create(16, 3, status); + return MeasureUnit::create(17, 3, status); } MeasureUnit MeasureUnit::getMegawatt() { - return MeasureUnit(16, 3); + return MeasureUnit(17, 3); } MeasureUnit *MeasureUnit::createMilliwatt(UErrorCode &status) { - return MeasureUnit::create(16, 4, status); + return MeasureUnit::create(17, 4, status); } MeasureUnit MeasureUnit::getMilliwatt() { - return MeasureUnit(16, 4); + return MeasureUnit(17, 4); } MeasureUnit *MeasureUnit::createWatt(UErrorCode &status) { - return MeasureUnit::create(16, 5, status); + return MeasureUnit::create(17, 5, status); } MeasureUnit MeasureUnit::getWatt() { - return MeasureUnit(16, 5); + return MeasureUnit(17, 5); } MeasureUnit *MeasureUnit::createAtmosphere(UErrorCode &status) { - return MeasureUnit::create(17, 0, status); + return MeasureUnit::create(18, 0, status); } MeasureUnit MeasureUnit::getAtmosphere() { - return MeasureUnit(17, 0); + return MeasureUnit(18, 0); +} + +MeasureUnit *MeasureUnit::createBar(UErrorCode &status) { + return MeasureUnit::create(18, 1, status); +} + +MeasureUnit MeasureUnit::getBar() { + return MeasureUnit(18, 1); } MeasureUnit *MeasureUnit::createHectopascal(UErrorCode &status) { - return MeasureUnit::create(17, 1, status); + return MeasureUnit::create(18, 2, status); } MeasureUnit MeasureUnit::getHectopascal() { - return MeasureUnit(17, 1); + return MeasureUnit(18, 2); } MeasureUnit *MeasureUnit::createInchHg(UErrorCode &status) { - return MeasureUnit::create(17, 2, status); + return MeasureUnit::create(18, 3, status); } MeasureUnit MeasureUnit::getInchHg() { - return MeasureUnit(17, 2); + return MeasureUnit(18, 3); } MeasureUnit *MeasureUnit::createKilopascal(UErrorCode &status) { - return MeasureUnit::create(17, 3, status); + return MeasureUnit::create(18, 4, status); } MeasureUnit MeasureUnit::getKilopascal() { - return MeasureUnit(17, 3); + return MeasureUnit(18, 4); } MeasureUnit *MeasureUnit::createMegapascal(UErrorCode &status) { - return MeasureUnit::create(17, 4, status); + return MeasureUnit::create(18, 5, status); } MeasureUnit MeasureUnit::getMegapascal() { - return MeasureUnit(17, 4); + return MeasureUnit(18, 5); } MeasureUnit *MeasureUnit::createMillibar(UErrorCode &status) { - return MeasureUnit::create(17, 5, status); + return MeasureUnit::create(18, 6, status); } MeasureUnit MeasureUnit::getMillibar() { - return MeasureUnit(17, 5); + return MeasureUnit(18, 6); } MeasureUnit *MeasureUnit::createMillimeterOfMercury(UErrorCode &status) { - return MeasureUnit::create(17, 6, status); + return MeasureUnit::create(18, 7, status); } MeasureUnit MeasureUnit::getMillimeterOfMercury() { - return MeasureUnit(17, 6); + return MeasureUnit(18, 7); +} + +MeasureUnit *MeasureUnit::createPascal(UErrorCode &status) { + return MeasureUnit::create(18, 8, status); +} + +MeasureUnit MeasureUnit::getPascal() { + return MeasureUnit(18, 8); } MeasureUnit *MeasureUnit::createPoundPerSquareInch(UErrorCode &status) { - return MeasureUnit::create(17, 7, status); + return MeasureUnit::create(18, 9, status); } MeasureUnit MeasureUnit::getPoundPerSquareInch() { - return MeasureUnit(17, 7); + return MeasureUnit(18, 9); } MeasureUnit *MeasureUnit::createKilometerPerHour(UErrorCode &status) { - return MeasureUnit::create(18, 0, status); + return MeasureUnit::create(19, 0, status); } MeasureUnit MeasureUnit::getKilometerPerHour() { - return MeasureUnit(18, 0); + return MeasureUnit(19, 0); } MeasureUnit *MeasureUnit::createKnot(UErrorCode &status) { - return MeasureUnit::create(18, 1, status); + return MeasureUnit::create(19, 1, status); } MeasureUnit MeasureUnit::getKnot() { - return MeasureUnit(18, 1); + return MeasureUnit(19, 1); } MeasureUnit *MeasureUnit::createMeterPerSecond(UErrorCode &status) { - return MeasureUnit::create(18, 2, status); + return MeasureUnit::create(19, 2, status); } MeasureUnit MeasureUnit::getMeterPerSecond() { - return MeasureUnit(18, 2); + return MeasureUnit(19, 2); } MeasureUnit *MeasureUnit::createMilePerHour(UErrorCode &status) { - return MeasureUnit::create(18, 3, status); + return MeasureUnit::create(19, 3, status); } MeasureUnit MeasureUnit::getMilePerHour() { - return MeasureUnit(18, 3); + return MeasureUnit(19, 3); } MeasureUnit *MeasureUnit::createCelsius(UErrorCode &status) { - return MeasureUnit::create(19, 0, status); + return MeasureUnit::create(20, 0, status); } MeasureUnit MeasureUnit::getCelsius() { - return MeasureUnit(19, 0); + return MeasureUnit(20, 0); } MeasureUnit *MeasureUnit::createFahrenheit(UErrorCode &status) { - return MeasureUnit::create(19, 1, status); + return MeasureUnit::create(20, 1, status); } MeasureUnit MeasureUnit::getFahrenheit() { - return MeasureUnit(19, 1); + return MeasureUnit(20, 1); } MeasureUnit *MeasureUnit::createGenericTemperature(UErrorCode &status) { - return MeasureUnit::create(19, 2, status); + return MeasureUnit::create(20, 2, status); } MeasureUnit MeasureUnit::getGenericTemperature() { - return MeasureUnit(19, 2); + return MeasureUnit(20, 2); } MeasureUnit *MeasureUnit::createKelvin(UErrorCode &status) { - return MeasureUnit::create(19, 3, status); + return MeasureUnit::create(20, 3, status); } MeasureUnit MeasureUnit::getKelvin() { - return MeasureUnit(19, 3); + return MeasureUnit(20, 3); } MeasureUnit *MeasureUnit::createNewtonMeter(UErrorCode &status) { - return MeasureUnit::create(20, 0, status); + return MeasureUnit::create(21, 0, status); } MeasureUnit MeasureUnit::getNewtonMeter() { - return MeasureUnit(20, 0); + return MeasureUnit(21, 0); } MeasureUnit *MeasureUnit::createPoundFoot(UErrorCode &status) { - return MeasureUnit::create(20, 1, status); + return MeasureUnit::create(21, 1, status); } MeasureUnit MeasureUnit::getPoundFoot() { - return MeasureUnit(20, 1); + return MeasureUnit(21, 1); } MeasureUnit *MeasureUnit::createAcreFoot(UErrorCode &status) { - return MeasureUnit::create(21, 0, status); + return MeasureUnit::create(22, 0, status); } MeasureUnit MeasureUnit::getAcreFoot() { - return MeasureUnit(21, 0); + return MeasureUnit(22, 0); } MeasureUnit *MeasureUnit::createBarrel(UErrorCode &status) { - return MeasureUnit::create(21, 1, status); + return MeasureUnit::create(22, 1, status); } MeasureUnit MeasureUnit::getBarrel() { - return MeasureUnit(21, 1); + return MeasureUnit(22, 1); } MeasureUnit *MeasureUnit::createBushel(UErrorCode &status) { - return MeasureUnit::create(21, 2, status); + return MeasureUnit::create(22, 2, status); } MeasureUnit MeasureUnit::getBushel() { - return MeasureUnit(21, 2); + return MeasureUnit(22, 2); } MeasureUnit *MeasureUnit::createCentiliter(UErrorCode &status) { - return MeasureUnit::create(21, 3, status); + return MeasureUnit::create(22, 3, status); } MeasureUnit MeasureUnit::getCentiliter() { - return MeasureUnit(21, 3); + return MeasureUnit(22, 3); } MeasureUnit *MeasureUnit::createCubicCentimeter(UErrorCode &status) { - return MeasureUnit::create(21, 4, status); + return MeasureUnit::create(22, 4, status); } MeasureUnit MeasureUnit::getCubicCentimeter() { - return MeasureUnit(21, 4); + return MeasureUnit(22, 4); } MeasureUnit *MeasureUnit::createCubicFoot(UErrorCode &status) { - return MeasureUnit::create(21, 5, status); + return MeasureUnit::create(22, 5, status); } MeasureUnit MeasureUnit::getCubicFoot() { - return MeasureUnit(21, 5); + return MeasureUnit(22, 5); } MeasureUnit *MeasureUnit::createCubicInch(UErrorCode &status) { - return MeasureUnit::create(21, 6, status); + return MeasureUnit::create(22, 6, status); } MeasureUnit MeasureUnit::getCubicInch() { - return MeasureUnit(21, 6); + return MeasureUnit(22, 6); } MeasureUnit *MeasureUnit::createCubicKilometer(UErrorCode &status) { - return MeasureUnit::create(21, 7, status); + return MeasureUnit::create(22, 7, status); } MeasureUnit MeasureUnit::getCubicKilometer() { - return MeasureUnit(21, 7); + return MeasureUnit(22, 7); } MeasureUnit *MeasureUnit::createCubicMeter(UErrorCode &status) { - return MeasureUnit::create(21, 8, status); + return MeasureUnit::create(22, 8, status); } MeasureUnit MeasureUnit::getCubicMeter() { - return MeasureUnit(21, 8); + return MeasureUnit(22, 8); } MeasureUnit *MeasureUnit::createCubicMile(UErrorCode &status) { - return MeasureUnit::create(21, 9, status); + return MeasureUnit::create(22, 9, status); } MeasureUnit MeasureUnit::getCubicMile() { - return MeasureUnit(21, 9); + return MeasureUnit(22, 9); } MeasureUnit *MeasureUnit::createCubicYard(UErrorCode &status) { - return MeasureUnit::create(21, 10, status); + return MeasureUnit::create(22, 10, status); } MeasureUnit MeasureUnit::getCubicYard() { - return MeasureUnit(21, 10); + return MeasureUnit(22, 10); } MeasureUnit *MeasureUnit::createCup(UErrorCode &status) { - return MeasureUnit::create(21, 11, status); + return MeasureUnit::create(22, 11, status); } MeasureUnit MeasureUnit::getCup() { - return MeasureUnit(21, 11); + return MeasureUnit(22, 11); } MeasureUnit *MeasureUnit::createCupMetric(UErrorCode &status) { - return MeasureUnit::create(21, 12, status); + return MeasureUnit::create(22, 12, status); } MeasureUnit MeasureUnit::getCupMetric() { - return MeasureUnit(21, 12); + return MeasureUnit(22, 12); } MeasureUnit *MeasureUnit::createDeciliter(UErrorCode &status) { - return MeasureUnit::create(21, 13, status); + return MeasureUnit::create(22, 13, status); } MeasureUnit MeasureUnit::getDeciliter() { - return MeasureUnit(21, 13); + return MeasureUnit(22, 13); } MeasureUnit *MeasureUnit::createFluidOunce(UErrorCode &status) { - return MeasureUnit::create(21, 14, status); + return MeasureUnit::create(22, 14, status); } MeasureUnit MeasureUnit::getFluidOunce() { - return MeasureUnit(21, 14); + return MeasureUnit(22, 14); } MeasureUnit *MeasureUnit::createFluidOunceImperial(UErrorCode &status) { - return MeasureUnit::create(21, 15, status); + return MeasureUnit::create(22, 15, status); } MeasureUnit MeasureUnit::getFluidOunceImperial() { - return MeasureUnit(21, 15); + return MeasureUnit(22, 15); } MeasureUnit *MeasureUnit::createGallon(UErrorCode &status) { - return MeasureUnit::create(21, 16, status); + return MeasureUnit::create(22, 16, status); } MeasureUnit MeasureUnit::getGallon() { - return MeasureUnit(21, 16); + return MeasureUnit(22, 16); } MeasureUnit *MeasureUnit::createGallonImperial(UErrorCode &status) { - return MeasureUnit::create(21, 17, status); + return MeasureUnit::create(22, 17, status); } MeasureUnit MeasureUnit::getGallonImperial() { - return MeasureUnit(21, 17); + return MeasureUnit(22, 17); } MeasureUnit *MeasureUnit::createHectoliter(UErrorCode &status) { - return MeasureUnit::create(21, 18, status); + return MeasureUnit::create(22, 18, status); } MeasureUnit MeasureUnit::getHectoliter() { - return MeasureUnit(21, 18); + return MeasureUnit(22, 18); } MeasureUnit *MeasureUnit::createLiter(UErrorCode &status) { - return MeasureUnit::create(21, 19, status); + return MeasureUnit::create(22, 19, status); } MeasureUnit MeasureUnit::getLiter() { - return MeasureUnit(21, 19); + return MeasureUnit(22, 19); } MeasureUnit *MeasureUnit::createMegaliter(UErrorCode &status) { - return MeasureUnit::create(21, 20, status); + return MeasureUnit::create(22, 20, status); } MeasureUnit MeasureUnit::getMegaliter() { - return MeasureUnit(21, 20); + return MeasureUnit(22, 20); } MeasureUnit *MeasureUnit::createMilliliter(UErrorCode &status) { - return MeasureUnit::create(21, 21, status); + return MeasureUnit::create(22, 21, status); } MeasureUnit MeasureUnit::getMilliliter() { - return MeasureUnit(21, 21); + return MeasureUnit(22, 21); } MeasureUnit *MeasureUnit::createPint(UErrorCode &status) { - return MeasureUnit::create(21, 22, status); + return MeasureUnit::create(22, 22, status); } MeasureUnit MeasureUnit::getPint() { - return MeasureUnit(21, 22); + return MeasureUnit(22, 22); } MeasureUnit *MeasureUnit::createPintMetric(UErrorCode &status) { - return MeasureUnit::create(21, 23, status); + return MeasureUnit::create(22, 23, status); } MeasureUnit MeasureUnit::getPintMetric() { - return MeasureUnit(21, 23); + return MeasureUnit(22, 23); } MeasureUnit *MeasureUnit::createQuart(UErrorCode &status) { - return MeasureUnit::create(21, 24, status); + return MeasureUnit::create(22, 24, status); } MeasureUnit MeasureUnit::getQuart() { - return MeasureUnit(21, 24); + return MeasureUnit(22, 24); } MeasureUnit *MeasureUnit::createTablespoon(UErrorCode &status) { - return MeasureUnit::create(21, 25, status); + return MeasureUnit::create(22, 25, status); } MeasureUnit MeasureUnit::getTablespoon() { - return MeasureUnit(21, 25); + return MeasureUnit(22, 25); } MeasureUnit *MeasureUnit::createTeaspoon(UErrorCode &status) { - return MeasureUnit::create(21, 26, status); + return MeasureUnit::create(22, 26, status); } MeasureUnit MeasureUnit::getTeaspoon() { - return MeasureUnit(21, 26); + return MeasureUnit(22, 26); } // End generated code @@ -1923,7 +2027,7 @@ MeasureUnit &MeasureUnit::operator=(const MeasureUnit &other) { return *this; } -UObject *MeasureUnit::clone() const { +MeasureUnit *MeasureUnit::clone() const { return new MeasureUnit(*this); } diff --git a/deps/icu-small/source/i18n/measure.cpp b/deps/icu-small/source/i18n/measure.cpp index d9084f87db..bffa44215e 100644 --- a/deps/icu-small/source/i18n/measure.cpp +++ b/deps/icu-small/source/i18n/measure.cpp @@ -43,12 +43,12 @@ Measure& Measure::operator=(const Measure& other) { if (this != &other) { delete unit; number = other.number; - unit = (MeasureUnit*) other.unit->clone(); + unit = other.unit->clone(); } return *this; } -UObject *Measure::clone() const { +Measure *Measure::clone() const { return new Measure(*this); } diff --git a/deps/icu-small/source/i18n/msgfmt.cpp b/deps/icu-small/source/i18n/msgfmt.cpp index e39b26b969..3ca368ef95 100644 --- a/deps/icu-small/source/i18n/msgfmt.cpp +++ b/deps/icu-small/source/i18n/msgfmt.cpp @@ -436,7 +436,7 @@ MessageFormat::operator==(const Format& rhs) const // ------------------------------------- // Creates a copy of this MessageFormat, the caller owns the copy. -Format* +MessageFormat* MessageFormat::clone() const { return new MessageFormat(*this); @@ -813,7 +813,7 @@ MessageFormat::getFormats(int32_t& cnt) const // Get total required capacity first (it's refreshed on each call). int32_t totalCapacity = 0; - for (int32_t partIndex = 0; (partIndex = nextTopLevelArgStart(partIndex)) >= 0; ++totalCapacity) {}; + for (int32_t partIndex = 0; (partIndex = nextTopLevelArgStart(partIndex)) >= 0; ++totalCapacity) {} MessageFormat* t = const_cast<MessageFormat*> (this); cnt = 0; @@ -1873,7 +1873,7 @@ UBool MessageFormat::DummyFormat::operator==(const Format&) const { return TRUE; } -Format* MessageFormat::DummyFormat::clone() const { +MessageFormat::DummyFormat* MessageFormat::DummyFormat::clone() const { return new DummyFormat(); } diff --git a/deps/icu-small/source/i18n/name2uni.cpp b/deps/icu-small/source/i18n/name2uni.cpp index d901eb126a..90bca9d71b 100644 --- a/deps/icu-small/source/i18n/name2uni.cpp +++ b/deps/icu-small/source/i18n/name2uni.cpp @@ -100,7 +100,7 @@ NameUnicodeTransliterator::NameUnicodeTransliterator(const NameUnicodeTransliter /** * Transliterator API. */ -Transliterator* NameUnicodeTransliterator::clone(void) const { +NameUnicodeTransliterator* NameUnicodeTransliterator::clone() const { return new NameUnicodeTransliterator(*this); } diff --git a/deps/icu-small/source/i18n/name2uni.h b/deps/icu-small/source/i18n/name2uni.h index 4c743def32..44ad85fb82 100644 --- a/deps/icu-small/source/i18n/name2uni.h +++ b/deps/icu-small/source/i18n/name2uni.h @@ -49,7 +49,7 @@ public: * Transliterator API. * @return A copy of the object. */ - virtual Transliterator* clone(void) const; + virtual NameUnicodeTransliterator* clone() const; /** * ICU "poor man's RTTI", returns a UClassID for the actual class. diff --git a/deps/icu-small/source/i18n/nortrans.cpp b/deps/icu-small/source/i18n/nortrans.cpp index 589c82482e..6a8d2c7419 100644 --- a/deps/icu-small/source/i18n/nortrans.cpp +++ b/deps/icu-small/source/i18n/nortrans.cpp @@ -92,7 +92,7 @@ NormalizationTransliterator::NormalizationTransliterator(const NormalizationTran /** * Transliterator API. */ -Transliterator* NormalizationTransliterator::clone(void) const { +NormalizationTransliterator* NormalizationTransliterator::clone() const { return new NormalizationTransliterator(*this); } diff --git a/deps/icu-small/source/i18n/nortrans.h b/deps/icu-small/source/i18n/nortrans.h index d309452f9a..198ed29c95 100644 --- a/deps/icu-small/source/i18n/nortrans.h +++ b/deps/icu-small/source/i18n/nortrans.h @@ -44,7 +44,7 @@ class NormalizationTransliterator : public Transliterator { * Transliterator API. * @return A copy of the object. */ - virtual Transliterator* clone(void) const; + virtual NormalizationTransliterator* clone() const; /** * ICU "poor man's RTTI", returns a UClassID for the actual class. diff --git a/deps/icu-small/source/i18n/nounit.cpp b/deps/icu-small/source/i18n/nounit.cpp index db07387c59..076f76f199 100644 --- a/deps/icu-small/source/i18n/nounit.cpp +++ b/deps/icu-small/source/i18n/nounit.cpp @@ -29,7 +29,7 @@ NoUnit::NoUnit(const char* subtype) { NoUnit::NoUnit(const NoUnit& other) : MeasureUnit(other) { } -UObject* NoUnit::clone() const { +NoUnit* NoUnit::clone() const { return new NoUnit(*this); } diff --git a/deps/icu-small/source/i18n/nultrans.cpp b/deps/icu-small/source/i18n/nultrans.cpp index 62d1290ac7..439cc55d38 100644 --- a/deps/icu-small/source/i18n/nultrans.cpp +++ b/deps/icu-small/source/i18n/nultrans.cpp @@ -24,7 +24,7 @@ NullTransliterator::NullTransliterator() : Transliterator(UNICODE_STRING_SIMPLE( NullTransliterator::~NullTransliterator() {} -Transliterator* NullTransliterator::clone(void) const { +NullTransliterator* NullTransliterator::clone() const { return new NullTransliterator(); } diff --git a/deps/icu-small/source/i18n/nultrans.h b/deps/icu-small/source/i18n/nultrans.h index a01b04e9ba..36c92fa7b1 100644 --- a/deps/icu-small/source/i18n/nultrans.h +++ b/deps/icu-small/source/i18n/nultrans.h @@ -45,7 +45,7 @@ public: * Transliterator API. * @internal Use transliterator factory methods instead since this class will be removed in that release. */ - virtual Transliterator* clone(void) const; + virtual NullTransliterator* clone() const; /** * Implements {@link Transliterator#handleTransliterate}. diff --git a/deps/icu-small/source/i18n/number_affixutils.cpp b/deps/icu-small/source/i18n/number_affixutils.cpp index 3eb9c59bf4..1039a84c65 100644 --- a/deps/icu-small/source/i18n/number_affixutils.cpp +++ b/deps/icu-small/source/i18n/number_affixutils.cpp @@ -156,7 +156,7 @@ Field AffixUtils::getFieldForType(AffixPatternType type) { } int32_t -AffixUtils::unescape(const UnicodeString &affixPattern, NumberStringBuilder &output, int32_t position, +AffixUtils::unescape(const UnicodeString &affixPattern, FormattedStringBuilder &output, int32_t position, const SymbolProvider &provider, Field field, UErrorCode &status) { int32_t length = 0; AffixTag tag; @@ -230,7 +230,7 @@ UnicodeString AffixUtils::replaceType(const UnicodeString &affixPattern, AffixPa UnicodeString output(affixPattern); // copy if (affixPattern.length() == 0) { return output; - }; + } AffixTag tag; while (hasNext(tag, affixPattern)) { tag = nextToken(tag, affixPattern, status); @@ -246,7 +246,7 @@ bool AffixUtils::containsOnlySymbolsAndIgnorables(const UnicodeString& affixPatt const UnicodeSet& ignorables, UErrorCode& status) { if (affixPattern.length() == 0) { return true; - }; + } AffixTag tag; while (hasNext(tag, affixPattern)) { tag = nextToken(tag, affixPattern, status); @@ -262,7 +262,7 @@ void AffixUtils::iterateWithConsumer(const UnicodeString& affixPattern, TokenCon UErrorCode& status) { if (affixPattern.length() == 0) { return; - }; + } AffixTag tag; while (hasNext(tag, affixPattern)) { tag = nextToken(tag, affixPattern, status); diff --git a/deps/icu-small/source/i18n/number_affixutils.h b/deps/icu-small/source/i18n/number_affixutils.h index f011a54b31..5cfde61ffd 100644 --- a/deps/icu-small/source/i18n/number_affixutils.h +++ b/deps/icu-small/source/i18n/number_affixutils.h @@ -11,7 +11,7 @@ #include "number_types.h" #include "unicode/stringpiece.h" #include "unicode/unistr.h" -#include "number_stringbuilder.h" +#include "formatted_string_builder.h" #include "unicode/uniset.h" U_NAMESPACE_BEGIN namespace number { @@ -134,16 +134,16 @@ class U_I18N_API AffixUtils { /** * Executes the unescape state machine. Replaces the unquoted characters "-", "+", "%", "‰", and * "¤" with the corresponding symbols provided by the {@link SymbolProvider}, and inserts the - * result into the NumberStringBuilder at the requested location. + * result into the FormattedStringBuilder at the requested location. * * <p>Example input: "'-'¤x"; example output: "-$x" * * @param affixPattern The original string to be unescaped. - * @param output The NumberStringBuilder to mutate with the result. - * @param position The index into the NumberStringBuilder to insert the string. + * @param output The FormattedStringBuilder to mutate with the result. + * @param position The index into the FormattedStringBuilder to insert the string. * @param provider An object to generate locale symbols. */ - static int32_t unescape(const UnicodeString& affixPattern, NumberStringBuilder& output, + static int32_t unescape(const UnicodeString& affixPattern, FormattedStringBuilder& output, int32_t position, const SymbolProvider& provider, Field field, UErrorCode& status); diff --git a/deps/icu-small/source/i18n/number_asformat.cpp b/deps/icu-small/source/i18n/number_asformat.cpp index 9d3ea69f57..e876174fdc 100644 --- a/deps/icu-small/source/i18n/number_asformat.cpp +++ b/deps/icu-small/source/i18n/number_asformat.cpp @@ -43,7 +43,7 @@ UBool LocalizedNumberFormatterAsFormat::operator==(const Format& other) const { return fFormatter.toSkeleton(localStatus) == _other->fFormatter.toSkeleton(localStatus); } -Format* LocalizedNumberFormatterAsFormat::clone() const { +LocalizedNumberFormatterAsFormat* LocalizedNumberFormatterAsFormat::clone() const { return new LocalizedNumberFormatterAsFormat(*this); } @@ -62,12 +62,12 @@ UnicodeString& LocalizedNumberFormatterAsFormat::format(const Formattable& obj, // always return first occurrence: pos.setBeginIndex(0); pos.setEndIndex(0); - bool found = data.getStringRef().nextFieldPosition(pos, status); + bool found = data.nextFieldPosition(pos, status); if (found && appendTo.length() != 0) { pos.setBeginIndex(pos.getBeginIndex() + appendTo.length()); pos.setEndIndex(pos.getEndIndex() + appendTo.length()); } - appendTo.append(data.getStringRef().toTempUnicodeString()); + appendTo.append(data.toTempString(status)); return appendTo; } @@ -84,10 +84,10 @@ UnicodeString& LocalizedNumberFormatterAsFormat::format(const Formattable& obj, if (U_FAILURE(status)) { return appendTo; } - appendTo.append(data.getStringRef().toTempUnicodeString()); + appendTo.append(data.toTempString(status)); if (posIter != nullptr) { FieldPositionIteratorHandler fpih(posIter, status); - data.getStringRef().getAllFieldPositions(fpih, status); + data.getAllFieldPositions(fpih, status); } return appendTo; } diff --git a/deps/icu-small/source/i18n/number_asformat.h b/deps/icu-small/source/i18n/number_asformat.h index bf82d72ae3..7b0a1dee6f 100644 --- a/deps/icu-small/source/i18n/number_asformat.h +++ b/deps/icu-small/source/i18n/number_asformat.h @@ -45,7 +45,7 @@ class U_I18N_API LocalizedNumberFormatterAsFormat : public Format { /** * Creates a copy of this object. */ - Format* clone() const U_OVERRIDE; + LocalizedNumberFormatterAsFormat* clone() const U_OVERRIDE; /** * Formats a Number using the wrapped LocalizedNumberFormatter. The provided formattable must be a diff --git a/deps/icu-small/source/i18n/number_compact.cpp b/deps/icu-small/source/i18n/number_compact.cpp index f330251be3..3d259999d6 100644 --- a/deps/icu-small/source/i18n/number_compact.cpp +++ b/deps/icu-small/source/i18n/number_compact.cpp @@ -272,15 +272,15 @@ void CompactHandler::processQuantity(DecimalQuantity &quantity, MicroProps &micr parent->processQuantity(quantity, micros, status); if (U_FAILURE(status)) { return; } - // Treat zero as if it had magnitude 0 + // Treat zero, NaN, and infinity as if they had magnitude 0 int32_t magnitude; - if (quantity.isZero()) { + if (quantity.isZeroish()) { magnitude = 0; micros.rounder.apply(quantity, status); } else { // TODO: Revisit chooseMultiplierAndApply int32_t multiplier = micros.rounder.chooseMultiplierAndApply(quantity, data, status); - magnitude = quantity.isZero() ? 0 : quantity.getMagnitude(); + magnitude = quantity.isZeroish() ? 0 : quantity.getMagnitude(); magnitude -= multiplier; } diff --git a/deps/icu-small/source/i18n/number_currencysymbols.cpp b/deps/icu-small/source/i18n/number_currencysymbols.cpp index 0b79d6596f..4d6fb2cb1d 100644 --- a/deps/icu-small/source/i18n/number_currencysymbols.cpp +++ b/deps/icu-small/source/i18n/number_currencysymbols.cpp @@ -53,13 +53,12 @@ UnicodeString CurrencySymbols::getCurrencySymbol(UErrorCode& status) const { UnicodeString CurrencySymbols::loadSymbol(UCurrNameStyle selector, UErrorCode& status) const { const char16_t* isoCode = fCurrency.getISOCurrency(); - UBool ignoredIsChoiceFormatFillIn = FALSE; int32_t symbolLen = 0; const char16_t* symbol = ucurr_getName( isoCode, fLocaleName.data(), selector, - &ignoredIsChoiceFormatFillIn, + nullptr /* isChoiceFormat */, &symbolLen, &status); // If given an unknown currency, ucurr_getName returns the input string, which we can't alias safely! @@ -82,12 +81,11 @@ UnicodeString CurrencySymbols::getIntlCurrencySymbol(UErrorCode&) const { UnicodeString CurrencySymbols::getPluralName(StandardPlural::Form plural, UErrorCode& status) const { const char16_t* isoCode = fCurrency.getISOCurrency(); - UBool isChoiceFormat = FALSE; int32_t symbolLen = 0; const char16_t* symbol = ucurr_getPluralName( isoCode, fLocaleName.data(), - &isChoiceFormat, + nullptr /* isChoiceFormat */, StandardPlural::getKeyword(plural), &symbolLen, &status); diff --git a/deps/icu-small/source/i18n/number_decimalquantity.cpp b/deps/icu-small/source/i18n/number_decimalquantity.cpp index d899c27671..2c4c2ce7e9 100644 --- a/deps/icu-small/source/i18n/number_decimalquantity.cpp +++ b/deps/icu-small/source/i18n/number_decimalquantity.cpp @@ -205,7 +205,7 @@ void DecimalQuantity::roundToIncrement(double roundingIncrement, RoundingMode ro } void DecimalQuantity::multiplyBy(const DecNum& multiplicand, UErrorCode& status) { - if (isInfinite() || isZero() || isNaN()) { + if (isZeroish()) { return; } // Convert to DecNum, multiply, and convert back. @@ -218,7 +218,7 @@ void DecimalQuantity::multiplyBy(const DecNum& multiplicand, UErrorCode& status) } void DecimalQuantity::divideBy(const DecNum& divisor, UErrorCode& status) { - if (isInfinite() || isZero() || isNaN()) { + if (isZeroish()) { return; } // Convert to DecNum, multiply, and convert back. @@ -318,8 +318,14 @@ bool DecimalQuantity::isNegative() const { return (flags & NEGATIVE_FLAG) != 0; } -int8_t DecimalQuantity::signum() const { - return isNegative() ? -1 : isZero() ? 0 : 1; +Signum DecimalQuantity::signum() const { + if (isNegative()) { + return SIGNUM_NEG; + } else if (isZeroish() && !isInfinite()) { + return SIGNUM_ZERO; + } else { + return SIGNUM_POS; + } } bool DecimalQuantity::isInfinite() const { @@ -330,7 +336,7 @@ bool DecimalQuantity::isNaN() const { return (flags & NAN_FLAG) != 0; } -bool DecimalQuantity::isZero() const { +bool DecimalQuantity::isZeroish() const { return precision == 0; } @@ -548,7 +554,10 @@ uint64_t DecimalQuantity::toFractionLong(bool includeTrailingZeros) const { } bool DecimalQuantity::fitsInLong(bool ignoreFraction) const { - if (isZero()) { + if (isInfinite() || isNaN()) { + return false; + } + if (isZeroish()) { return true; } if (scale < 0 && !ignoreFraction) { diff --git a/deps/icu-small/source/i18n/number_decimalquantity.h b/deps/icu-small/source/i18n/number_decimalquantity.h index 06cc836c77..4ec6c5a5b2 100644 --- a/deps/icu-small/source/i18n/number_decimalquantity.h +++ b/deps/icu-small/source/i18n/number_decimalquantity.h @@ -146,14 +146,17 @@ class U_I18N_API DecimalQuantity : public IFixedDecimal, public UMemory { */ int32_t getMagnitude() const; - /** @return Whether the value represented by this {@link DecimalQuantity} is zero. */ - bool isZero() const; + /** + * @return Whether the value represented by this {@link DecimalQuantity} is + * zero, infinity, or NaN. + */ + bool isZeroish() const; /** @return Whether the value represented by this {@link DecimalQuantity} is less than zero. */ bool isNegative() const; - /** @return -1 if the value is negative; 1 if positive; or 0 if zero. */ - int8_t signum() const; + /** @return The appropriate value from the Signum enum. */ + Signum signum() const; /** @return Whether the value represented by this {@link DecimalQuantity} is infinite. */ bool isInfinite() const U_OVERRIDE; diff --git a/deps/icu-small/source/i18n/number_decnum.h b/deps/icu-small/source/i18n/number_decnum.h index a7793470b5..0c7399dbdd 100644 --- a/deps/icu-small/source/i18n/number_decnum.h +++ b/deps/icu-small/source/i18n/number_decnum.h @@ -55,6 +55,8 @@ class U_I18N_API DecNum : public UMemory { bool isZero() const; + void toString(ByteSink& output, UErrorCode& status) const; + inline const decNumber* getRawDecNumber() const { return fData.getAlias(); } diff --git a/deps/icu-small/source/i18n/number_fluent.cpp b/deps/icu-small/source/i18n/number_fluent.cpp index 09e0905609..2dbd2fa6cd 100644 --- a/deps/icu-small/source/i18n/number_fluent.cpp +++ b/deps/icu-small/source/i18n/number_fluent.cpp @@ -696,8 +696,8 @@ void LocalizedNumberFormatter::formatImpl(impl::UFormattedNumberData* results, U void LocalizedNumberFormatter::getAffixImpl(bool isPrefix, bool isNegative, UnicodeString& result, UErrorCode& status) const { - NumberStringBuilder string; - auto signum = static_cast<int8_t>(isNegative ? -1 : 1); + FormattedStringBuilder string; + auto signum = static_cast<Signum>(isNegative ? SIGNUM_NEG : SIGNUM_POS); // Always return affixes for plural form OTHER. static const StandardPlural::Form plural = StandardPlural::OTHER; int32_t prefixLength; diff --git a/deps/icu-small/source/i18n/number_formatimpl.cpp b/deps/icu-small/source/i18n/number_formatimpl.cpp index 08b833beb7..2e2c4a9620 100644 --- a/deps/icu-small/source/i18n/number_formatimpl.cpp +++ b/deps/icu-small/source/i18n/number_formatimpl.cpp @@ -72,7 +72,7 @@ NumberFormatterImpl::NumberFormatterImpl(const MacroProps& macros, UErrorCode& s } int32_t NumberFormatterImpl::formatStatic(const MacroProps& macros, DecimalQuantity& inValue, - NumberStringBuilder& outString, UErrorCode& status) { + FormattedStringBuilder& outString, UErrorCode& status) { NumberFormatterImpl impl(macros, false, status); MicroProps& micros = impl.preProcessUnsafe(inValue, status); if (U_FAILURE(status)) { return 0; } @@ -81,9 +81,9 @@ int32_t NumberFormatterImpl::formatStatic(const MacroProps& macros, DecimalQuant return length; } -int32_t NumberFormatterImpl::getPrefixSuffixStatic(const MacroProps& macros, int8_t signum, +int32_t NumberFormatterImpl::getPrefixSuffixStatic(const MacroProps& macros, Signum signum, StandardPlural::Form plural, - NumberStringBuilder& outString, UErrorCode& status) { + FormattedStringBuilder& outString, UErrorCode& status) { NumberFormatterImpl impl(macros, false, status); return impl.getPrefixSuffixUnsafe(signum, plural, outString, status); } @@ -93,7 +93,7 @@ int32_t NumberFormatterImpl::getPrefixSuffixStatic(const MacroProps& macros, int // The "unsafe" method simply re-uses fMicros, eliminating the extra copy operation. // See MicroProps::processQuantity() for details. -int32_t NumberFormatterImpl::format(DecimalQuantity& inValue, NumberStringBuilder& outString, +int32_t NumberFormatterImpl::format(DecimalQuantity& inValue, FormattedStringBuilder& outString, UErrorCode& status) const { MicroProps micros; preProcess(inValue, micros, status); @@ -129,8 +129,8 @@ MicroProps& NumberFormatterImpl::preProcessUnsafe(DecimalQuantity& inValue, UErr return fMicros; } -int32_t NumberFormatterImpl::getPrefixSuffix(int8_t signum, StandardPlural::Form plural, - NumberStringBuilder& outString, UErrorCode& status) const { +int32_t NumberFormatterImpl::getPrefixSuffix(Signum signum, StandardPlural::Form plural, + FormattedStringBuilder& outString, UErrorCode& status) const { if (U_FAILURE(status)) { return 0; } // #13453: DecimalFormat wants the affixes from the pattern only (modMiddle, aka pattern modifier). // Safe path: use fImmutablePatternModifier. @@ -140,8 +140,8 @@ int32_t NumberFormatterImpl::getPrefixSuffix(int8_t signum, StandardPlural::Form return modifier->getPrefixLength(); } -int32_t NumberFormatterImpl::getPrefixSuffixUnsafe(int8_t signum, StandardPlural::Form plural, - NumberStringBuilder& outString, UErrorCode& status) { +int32_t NumberFormatterImpl::getPrefixSuffixUnsafe(Signum signum, StandardPlural::Form plural, + FormattedStringBuilder& outString, UErrorCode& status) { if (U_FAILURE(status)) { return 0; } // #13453: DecimalFormat wants the affixes from the pattern only (modMiddle, aka pattern modifier). // Unsafe path: use fPatternModifier. @@ -215,7 +215,12 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe, if (macros.symbols.isDecimalFormatSymbols()) { fMicros.symbols = macros.symbols.getDecimalFormatSymbols(); } else { - fMicros.symbols = new DecimalFormatSymbols(macros.locale, *ns, status); + auto newSymbols = new DecimalFormatSymbols(macros.locale, *ns, status); + if (newSymbols == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return nullptr; + } + fMicros.symbols = newSymbols; // Give ownership to the NumberFormatterImpl. fSymbols.adoptInstead(fMicros.symbols); } @@ -229,7 +234,11 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe, if (info.exists) { pattern = info.pattern; // It's clunky to clone an object here, but this code is not frequently executed. - auto* symbols = new DecimalFormatSymbols(*fMicros.symbols); + auto symbols = new DecimalFormatSymbols(*fMicros.symbols); + if (symbols == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return nullptr; + } fMicros.symbols = symbols; fSymbols.adoptInstead(symbols); symbols->setSymbol( @@ -260,6 +269,10 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe, pattern = utils::getPatternForStyle(macros.locale, nsName, patternStyle, status); } auto patternInfo = new ParsedPatternInfo(); + if (patternInfo == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return nullptr; + } fPatternInfo.adoptInstead(patternInfo); PatternParser::parseToPatternInfo(UnicodeString(pattern), *patternInfo, status); @@ -337,7 +350,12 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe, // Inner modifier (scientific notation) if (macros.notation.fType == Notation::NTN_SCIENTIFIC) { - fScientificHandler.adoptInstead(new ScientificHandler(¯os.notation, fMicros.symbols, chain)); + auto newScientificHandler = new ScientificHandler(¯os.notation, fMicros.symbols, chain); + if (newScientificHandler == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return nullptr; + } + fScientificHandler.adoptInstead(newScientificHandler); chain = fScientificHandler.getAlias(); } else { // No inner modifier required @@ -346,6 +364,10 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe, // Middle modifier (patterns, positive/negative, currency symbols, percent) auto patternModifier = new MutablePatternModifier(false); + if (patternModifier == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return nullptr; + } fPatternModifier.adoptInstead(patternModifier); patternModifier->setPatternInfo( macros.affixProvider != nullptr ? macros.affixProvider @@ -401,16 +423,20 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe, if (macros.notation.fType == Notation::NTN_COMPACT) { CompactType compactType = (isCurrency && unitWidth != UNUM_UNIT_WIDTH_FULL_NAME) ? CompactType::TYPE_CURRENCY : CompactType::TYPE_DECIMAL; - fCompactHandler.adoptInstead( - new CompactHandler( - macros.notation.fUnion.compactStyle, - macros.locale, - nsName, - compactType, - resolvePluralRules(macros.rules, macros.locale, status), - safe ? patternModifier : nullptr, - chain, - status)); + auto newCompactHandler = new CompactHandler( + macros.notation.fUnion.compactStyle, + macros.locale, + nsName, + compactType, + resolvePluralRules(macros.rules, macros.locale, status), + safe ? patternModifier : nullptr, + chain, + status); + if (newCompactHandler == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return nullptr; + } + fCompactHandler.adoptInstead(newCompactHandler); chain = fCompactHandler.getAlias(); } @@ -430,7 +456,7 @@ NumberFormatterImpl::resolvePluralRules(const PluralRules* rulesPtr, const Local return fRules.getAlias(); } -int32_t NumberFormatterImpl::writeAffixes(const MicroProps& micros, NumberStringBuilder& string, +int32_t NumberFormatterImpl::writeAffixes(const MicroProps& micros, FormattedStringBuilder& string, int32_t start, int32_t end, UErrorCode& status) { // Always apply the inner modifier (which is "strong"). int32_t length = micros.modInner->apply(string, start, end, status); @@ -445,7 +471,7 @@ int32_t NumberFormatterImpl::writeAffixes(const MicroProps& micros, NumberString } int32_t NumberFormatterImpl::writeNumber(const MicroProps& micros, DecimalQuantity& quantity, - NumberStringBuilder& string, int32_t index, + FormattedStringBuilder& string, int32_t index, UErrorCode& status) { int32_t length = 0; if (quantity.isInfinite()) { @@ -487,7 +513,7 @@ int32_t NumberFormatterImpl::writeNumber(const MicroProps& micros, DecimalQuanti } int32_t NumberFormatterImpl::writeIntegerDigits(const MicroProps& micros, DecimalQuantity& quantity, - NumberStringBuilder& string, int32_t index, + FormattedStringBuilder& string, int32_t index, UErrorCode& status) { int length = 0; int integerCount = quantity.getUpperDisplayMagnitude() + 1; @@ -513,7 +539,7 @@ int32_t NumberFormatterImpl::writeIntegerDigits(const MicroProps& micros, Decima } int32_t NumberFormatterImpl::writeFractionDigits(const MicroProps& micros, DecimalQuantity& quantity, - NumberStringBuilder& string, int32_t index, + FormattedStringBuilder& string, int32_t index, UErrorCode& status) { int length = 0; int fractionCount = -quantity.getLowerDisplayMagnitude(); diff --git a/deps/icu-small/source/i18n/number_formatimpl.h b/deps/icu-small/source/i18n/number_formatimpl.h index fd8708c532..206c5f58c5 100644 --- a/deps/icu-small/source/i18n/number_formatimpl.h +++ b/deps/icu-small/source/i18n/number_formatimpl.h @@ -8,7 +8,7 @@ #define __NUMBER_FORMATIMPL_H__ #include "number_types.h" -#include "number_stringbuilder.h" +#include "formatted_string_builder.h" #include "number_patternstring.h" #include "number_utils.h" #include "number_patternmodifier.h" @@ -35,7 +35,7 @@ class NumberFormatterImpl : public UMemory { * Builds and evaluates an "unsafe" MicroPropsGenerator, which is cheaper but can be used only once. */ static int32_t - formatStatic(const MacroProps ¯os, DecimalQuantity &inValue, NumberStringBuilder &outString, + formatStatic(const MacroProps ¯os, DecimalQuantity &inValue, FormattedStringBuilder &outString, UErrorCode &status); /** @@ -44,14 +44,14 @@ class NumberFormatterImpl : public UMemory { * @return The index into the output at which the prefix ends and the suffix starts; in other words, * the prefix length. */ - static int32_t getPrefixSuffixStatic(const MacroProps& macros, int8_t signum, - StandardPlural::Form plural, NumberStringBuilder& outString, + static int32_t getPrefixSuffixStatic(const MacroProps& macros, Signum signum, + StandardPlural::Form plural, FormattedStringBuilder& outString, UErrorCode& status); /** * Evaluates the "safe" MicroPropsGenerator created by "fromMacros". */ - int32_t format(DecimalQuantity& inValue, NumberStringBuilder& outString, UErrorCode& status) const; + int32_t format(DecimalQuantity& inValue, FormattedStringBuilder& outString, UErrorCode& status) const; /** * Like format(), but saves the result into an output MicroProps without additional processing. @@ -61,7 +61,7 @@ class NumberFormatterImpl : public UMemory { /** * Like getPrefixSuffixStatic() but uses the safe compiled object. */ - int32_t getPrefixSuffix(int8_t signum, StandardPlural::Form plural, NumberStringBuilder& outString, + int32_t getPrefixSuffix(Signum signum, StandardPlural::Form plural, FormattedStringBuilder& outString, UErrorCode& status) const; const MicroProps& getRawMicroProps() const { @@ -73,12 +73,12 @@ class NumberFormatterImpl : public UMemory { * This method formats only the main number, not affixes. */ static int32_t writeNumber(const MicroProps& micros, DecimalQuantity& quantity, - NumberStringBuilder& string, int32_t index, UErrorCode& status); + FormattedStringBuilder& string, int32_t index, UErrorCode& status); /** * Adds the affixes. Intended to be called immediately after formatNumber. */ - static int32_t writeAffixes(const MicroProps& micros, NumberStringBuilder& string, int32_t start, + static int32_t writeAffixes(const MicroProps& micros, FormattedStringBuilder& string, int32_t start, int32_t end, UErrorCode& status); private: @@ -109,8 +109,8 @@ class NumberFormatterImpl : public UMemory { MicroProps& preProcessUnsafe(DecimalQuantity &inValue, UErrorCode &status); - int32_t getPrefixSuffixUnsafe(int8_t signum, StandardPlural::Form plural, - NumberStringBuilder& outString, UErrorCode& status); + int32_t getPrefixSuffixUnsafe(Signum signum, StandardPlural::Form plural, + FormattedStringBuilder& outString, UErrorCode& status); /** * If rulesPtr is non-null, return it. Otherwise, return a PluralRules owned by this object for the @@ -136,11 +136,11 @@ class NumberFormatterImpl : public UMemory { macrosToMicroGenerator(const MacroProps ¯os, bool safe, UErrorCode &status); static int32_t - writeIntegerDigits(const MicroProps µs, DecimalQuantity &quantity, NumberStringBuilder &string, + writeIntegerDigits(const MicroProps µs, DecimalQuantity &quantity, FormattedStringBuilder &string, int32_t index, UErrorCode &status); static int32_t - writeFractionDigits(const MicroProps µs, DecimalQuantity &quantity, NumberStringBuilder &string, + writeFractionDigits(const MicroProps µs, DecimalQuantity &quantity, FormattedStringBuilder &string, int32_t index, UErrorCode &status); }; diff --git a/deps/icu-small/source/i18n/number_longnames.cpp b/deps/icu-small/source/i18n/number_longnames.cpp index 0cd160042a..817aa0e0d9 100644 --- a/deps/icu-small/source/i18n/number_longnames.cpp +++ b/deps/icu-small/source/i18n/number_longnames.cpp @@ -148,12 +148,11 @@ void getCurrencyLongNameData(const Locale &locale, const CurrencyUnit ¤cy, if (pattern.isBogus()) { continue; } - UBool isChoiceFormat = FALSE; int32_t longNameLen = 0; const char16_t *longName = ucurr_getPluralName( currency.getISOCurrency(), locale.getName(), - &isChoiceFormat, + nullptr /* isChoiceFormat */, StandardPlural::getKeyword(static_cast<StandardPlural::Form>(i)), &longNameLen, &status); @@ -265,6 +264,26 @@ UnicodeString LongNameHandler::getUnitDisplayName( return simpleFormats[DNAM_INDEX]; } +UnicodeString LongNameHandler::getUnitPattern( + const Locale& loc, + const MeasureUnit& unit, + UNumberUnitWidth width, + StandardPlural::Form pluralForm, + UErrorCode& status) { + if (U_FAILURE(status)) { + return ICU_Utility::makeBogusString(); + } + UnicodeString simpleFormats[ARRAY_LENGTH]; + getMeasureData(loc, unit, width, simpleFormats, status); + // The above already handles fallback from other widths to short + if (U_FAILURE(status)) { + return ICU_Utility::makeBogusString(); + } + // Now handle fallback from other plural forms to OTHER + return (!(simpleFormats[pluralForm]).isBogus())? simpleFormats[pluralForm]: + simpleFormats[StandardPlural::Form::OTHER]; +} + LongNameHandler* LongNameHandler::forCurrencyLongNames(const Locale &loc, const CurrencyUnit ¤cy, const PluralRules *rules, const MicroPropsGenerator *parent, @@ -289,7 +308,7 @@ void LongNameHandler::simpleFormatsToModifiers(const UnicodeString *simpleFormat if (U_FAILURE(status)) { return; } SimpleFormatter compiledFormatter(simpleFormat, 0, 1, status); if (U_FAILURE(status)) { return; } - fModifiers[i] = SimpleModifier(compiledFormatter, field, false, {this, 0, plural}); + fModifiers[i] = SimpleModifier(compiledFormatter, field, false, {this, SIGNUM_ZERO, plural}); } } @@ -306,7 +325,7 @@ void LongNameHandler::multiSimpleFormatsToModifiers(const UnicodeString *leadFor if (U_FAILURE(status)) { return; } SimpleFormatter compoundCompiled(compoundFormat, 0, 1, status); if (U_FAILURE(status)) { return; } - fModifiers[i] = SimpleModifier(compoundCompiled, field, false, {this, 0, plural}); + fModifiers[i] = SimpleModifier(compoundCompiled, field, false, {this, SIGNUM_ZERO, plural}); } } @@ -317,7 +336,7 @@ void LongNameHandler::processQuantity(DecimalQuantity &quantity, MicroProps &mic micros.modOuter = &fModifiers[pluralForm]; } -const Modifier* LongNameHandler::getModifier(int8_t /*signum*/, StandardPlural::Form plural) const { +const Modifier* LongNameHandler::getModifier(Signum /*signum*/, StandardPlural::Form plural) const { return &fModifiers[plural]; } diff --git a/deps/icu-small/source/i18n/number_longnames.h b/deps/icu-small/source/i18n/number_longnames.h index 76fb82d744..a19425aa26 100644 --- a/deps/icu-small/source/i18n/number_longnames.h +++ b/deps/icu-small/source/i18n/number_longnames.h @@ -22,6 +22,13 @@ class LongNameHandler : public MicroPropsGenerator, public ModifierStore, public UNumberUnitWidth width, UErrorCode& status); + static UnicodeString getUnitPattern( + const Locale& loc, + const MeasureUnit& unit, + UNumberUnitWidth width, + StandardPlural::Form pluralForm, + UErrorCode& status); + static LongNameHandler* forCurrencyLongNames(const Locale &loc, const CurrencyUnit ¤cy, const PluralRules *rules, const MicroPropsGenerator *parent, UErrorCode &status); @@ -34,7 +41,7 @@ class LongNameHandler : public MicroPropsGenerator, public ModifierStore, public void processQuantity(DecimalQuantity &quantity, MicroProps µs, UErrorCode &status) const U_OVERRIDE; - const Modifier* getModifier(int8_t signum, StandardPlural::Form plural) const U_OVERRIDE; + const Modifier* getModifier(Signum signum, StandardPlural::Form plural) const U_OVERRIDE; private: SimpleModifier fModifiers[StandardPlural::Form::COUNT]; diff --git a/deps/icu-small/source/i18n/number_mapper.h b/deps/icu-small/source/i18n/number_mapper.h index d28e9cec39..de7d9c3865 100644 --- a/deps/icu-small/source/i18n/number_mapper.h +++ b/deps/icu-small/source/i18n/number_mapper.h @@ -126,8 +126,14 @@ struct DecimalFormatWarehouse { * TODO: Make some of these fields by value instead of by LocalPointer? */ struct DecimalFormatFields : public UMemory { + + DecimalFormatFields() {} + + DecimalFormatFields(const DecimalFormatProperties& propsToCopy) + : properties(propsToCopy) {} + /** The property bag corresponding to user-specified settings and settings from the pattern string. */ - LocalPointer<DecimalFormatProperties> properties; + DecimalFormatProperties properties; /** The symbols for the current locale. */ LocalPointer<const DecimalFormatSymbols> symbols; @@ -136,7 +142,7 @@ struct DecimalFormatFields : public UMemory { * The pre-computed formatter object. Setters cause this to be re-computed atomically. The {@link * #format} method uses the formatter directly without needing to synchronize. */ - LocalPointer<LocalizedNumberFormatter> formatter; + LocalizedNumberFormatter formatter; /** The lazy-computed parser for .parse() */ std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicParser = {}; @@ -148,7 +154,7 @@ struct DecimalFormatFields : public UMemory { DecimalFormatWarehouse warehouse; /** The effective properties as exported from the formatter object. Used by some getters. */ - LocalPointer<DecimalFormatProperties> exportedProperties; + DecimalFormatProperties exportedProperties; // Data for fastpath bool canUseFastFormat = false; diff --git a/deps/icu-small/source/i18n/number_modifiers.cpp b/deps/icu-small/source/i18n/number_modifiers.cpp index 1fcbe7b9b7..3a44f8f6f1 100644 --- a/deps/icu-small/source/i18n/number_modifiers.cpp +++ b/deps/icu-small/source/i18n/number_modifiers.cpp @@ -57,7 +57,7 @@ Modifier::Parameters::Parameters() : obj(nullptr) {} Modifier::Parameters::Parameters( - const ModifierStore* _obj, int8_t _signum, StandardPlural::Form _plural) + const ModifierStore* _obj, Signum _signum, StandardPlural::Form _plural) : obj(_obj), signum(_signum), plural(_plural) {} ModifierStore::~ModifierStore() = default; @@ -69,7 +69,7 @@ AdoptingModifierStore::~AdoptingModifierStore() { } -int32_t ConstantAffixModifier::apply(NumberStringBuilder &output, int leftIndex, int rightIndex, +int32_t ConstantAffixModifier::apply(FormattedStringBuilder &output, int leftIndex, int rightIndex, UErrorCode &status) const { // Insert the suffix first since inserting the prefix will change the rightIndex int length = output.insert(rightIndex, fSuffix, fField, status); @@ -154,7 +154,7 @@ SimpleModifier::SimpleModifier() : fField(UNUM_FIELD_COUNT), fStrong(false), fPrefixLength(0), fSuffixLength(0) { } -int32_t SimpleModifier::apply(NumberStringBuilder &output, int leftIndex, int rightIndex, +int32_t SimpleModifier::apply(FormattedStringBuilder &output, int leftIndex, int rightIndex, UErrorCode &status) const { return formatAsPrefixSuffix(output, leftIndex, rightIndex, status); } @@ -203,7 +203,7 @@ bool SimpleModifier::semanticallyEquivalent(const Modifier& other) const { int32_t -SimpleModifier::formatAsPrefixSuffix(NumberStringBuilder &result, int32_t startIndex, int32_t endIndex, +SimpleModifier::formatAsPrefixSuffix(FormattedStringBuilder &result, int32_t startIndex, int32_t endIndex, UErrorCode &status) const { if (fSuffixOffset == -1 && fPrefixLength + fSuffixLength > 0) { // There is no argument for the inner number; overwrite the entire segment with our string. @@ -227,7 +227,7 @@ SimpleModifier::formatAsPrefixSuffix(NumberStringBuilder &result, int32_t startI int32_t -SimpleModifier::formatTwoArgPattern(const SimpleFormatter& compiled, NumberStringBuilder& result, +SimpleModifier::formatTwoArgPattern(const SimpleFormatter& compiled, FormattedStringBuilder& result, int32_t index, int32_t* outPrefixLength, int32_t* outSuffixLength, Field field, UErrorCode& status) { const UnicodeString& compiledPattern = compiled.compiledPattern; @@ -284,7 +284,7 @@ SimpleModifier::formatTwoArgPattern(const SimpleFormatter& compiled, NumberStrin } -int32_t ConstantMultiFieldModifier::apply(NumberStringBuilder &output, int leftIndex, int rightIndex, +int32_t ConstantMultiFieldModifier::apply(FormattedStringBuilder &output, int leftIndex, int rightIndex, UErrorCode &status) const { int32_t length = output.insert(leftIndex, fPrefix, status); if (fOverwrite) { @@ -333,8 +333,8 @@ bool ConstantMultiFieldModifier::semanticallyEquivalent(const Modifier& other) c } -CurrencySpacingEnabledModifier::CurrencySpacingEnabledModifier(const NumberStringBuilder &prefix, - const NumberStringBuilder &suffix, +CurrencySpacingEnabledModifier::CurrencySpacingEnabledModifier(const FormattedStringBuilder &prefix, + const FormattedStringBuilder &suffix, bool overwrite, bool strong, const DecimalFormatSymbols &symbols, @@ -374,7 +374,7 @@ CurrencySpacingEnabledModifier::CurrencySpacingEnabledModifier(const NumberStrin } } -int32_t CurrencySpacingEnabledModifier::apply(NumberStringBuilder &output, int leftIndex, int rightIndex, +int32_t CurrencySpacingEnabledModifier::apply(FormattedStringBuilder &output, int leftIndex, int rightIndex, UErrorCode &status) const { // Currency spacing logic int length = 0; @@ -395,7 +395,7 @@ int32_t CurrencySpacingEnabledModifier::apply(NumberStringBuilder &output, int l } int32_t -CurrencySpacingEnabledModifier::applyCurrencySpacing(NumberStringBuilder &output, int32_t prefixStart, +CurrencySpacingEnabledModifier::applyCurrencySpacing(FormattedStringBuilder &output, int32_t prefixStart, int32_t prefixLen, int32_t suffixStart, int32_t suffixLen, const DecimalFormatSymbols &symbols, @@ -414,7 +414,7 @@ CurrencySpacingEnabledModifier::applyCurrencySpacing(NumberStringBuilder &output } int32_t -CurrencySpacingEnabledModifier::applyCurrencySpacingAffix(NumberStringBuilder &output, int32_t index, +CurrencySpacingEnabledModifier::applyCurrencySpacingAffix(FormattedStringBuilder &output, int32_t index, EAffix affix, const DecimalFormatSymbols &symbols, UErrorCode &status) { diff --git a/deps/icu-small/source/i18n/number_modifiers.h b/deps/icu-small/source/i18n/number_modifiers.h index 495128bb14..c84c6aa273 100644 --- a/deps/icu-small/source/i18n/number_modifiers.h +++ b/deps/icu-small/source/i18n/number_modifiers.h @@ -12,7 +12,7 @@ #include "unicode/uniset.h" #include "unicode/simpleformatter.h" #include "standardplural.h" -#include "number_stringbuilder.h" +#include "formatted_string_builder.h" #include "number_types.h" U_NAMESPACE_BEGIN namespace number { @@ -28,7 +28,7 @@ class U_I18N_API ConstantAffixModifier : public Modifier, public UObject { bool strong) : fPrefix(prefix), fSuffix(suffix), fField(field), fStrong(strong) {} - int32_t apply(NumberStringBuilder &output, int32_t leftIndex, int32_t rightIndex, + int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex, UErrorCode &status) const U_OVERRIDE; int32_t getPrefixLength() const U_OVERRIDE; @@ -64,7 +64,7 @@ class U_I18N_API SimpleModifier : public Modifier, public UMemory { // Default constructor for LongNameHandler.h SimpleModifier(); - int32_t apply(NumberStringBuilder &output, int32_t leftIndex, int32_t rightIndex, + int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex, UErrorCode &status) const U_OVERRIDE; int32_t getPrefixLength() const U_OVERRIDE; @@ -81,7 +81,7 @@ class U_I18N_API SimpleModifier : public Modifier, public UMemory { /** * TODO: This belongs in SimpleFormatterImpl. The only reason I haven't moved it there yet is because - * NumberStringBuilder is an internal class and SimpleFormatterImpl feels like it should not depend on it. + * FormattedStringBuilder is an internal class and SimpleFormatterImpl feels like it should not depend on it. * * <p> * Formats a value that is already stored inside the StringBuilder <code>result</code> between the indices @@ -100,22 +100,22 @@ class U_I18N_API SimpleModifier : public Modifier, public UMemory { * @return The number of characters (UTF-16 code points) that were added to the StringBuilder. */ int32_t - formatAsPrefixSuffix(NumberStringBuilder& result, int32_t startIndex, int32_t endIndex, + formatAsPrefixSuffix(FormattedStringBuilder& result, int32_t startIndex, int32_t endIndex, UErrorCode& status) const; /** * TODO: Like above, this belongs with the rest of the SimpleFormatterImpl code. - * I put it here so that the SimpleFormatter uses in NumberStringBuilder are near each other. + * I put it here so that the SimpleFormatter uses in FormattedStringBuilder are near each other. * * <p> - * Applies the compiled two-argument pattern to the NumberStringBuilder. + * Applies the compiled two-argument pattern to the FormattedStringBuilder. * * <p> * This method is optimized for the case where the prefix and suffix are often empty, such as * in the range pattern like "{0}-{1}". */ static int32_t - formatTwoArgPattern(const SimpleFormatter& compiled, NumberStringBuilder& result, + formatTwoArgPattern(const SimpleFormatter& compiled, FormattedStringBuilder& result, int32_t index, int32_t* outPrefixLength, int32_t* outSuffixLength, Field field, UErrorCode& status); @@ -131,13 +131,13 @@ class U_I18N_API SimpleModifier : public Modifier, public UMemory { /** * An implementation of {@link Modifier} that allows for multiple types of fields in the same modifier. Constructed - * based on the contents of two {@link NumberStringBuilder} instances (one for the prefix, one for the suffix). + * based on the contents of two {@link FormattedStringBuilder} instances (one for the prefix, one for the suffix). */ class U_I18N_API ConstantMultiFieldModifier : public Modifier, public UMemory { public: ConstantMultiFieldModifier( - const NumberStringBuilder &prefix, - const NumberStringBuilder &suffix, + const FormattedStringBuilder &prefix, + const FormattedStringBuilder &suffix, bool overwrite, bool strong, const Modifier::Parameters parameters) @@ -148,8 +148,8 @@ class U_I18N_API ConstantMultiFieldModifier : public Modifier, public UMemory { fParameters(parameters) {} ConstantMultiFieldModifier( - const NumberStringBuilder &prefix, - const NumberStringBuilder &suffix, + const FormattedStringBuilder &prefix, + const FormattedStringBuilder &suffix, bool overwrite, bool strong) : fPrefix(prefix), @@ -157,7 +157,7 @@ class U_I18N_API ConstantMultiFieldModifier : public Modifier, public UMemory { fOverwrite(overwrite), fStrong(strong) {} - int32_t apply(NumberStringBuilder &output, int32_t leftIndex, int32_t rightIndex, + int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex, UErrorCode &status) const U_OVERRIDE; int32_t getPrefixLength() const U_OVERRIDE; @@ -173,10 +173,10 @@ class U_I18N_API ConstantMultiFieldModifier : public Modifier, public UMemory { bool semanticallyEquivalent(const Modifier& other) const U_OVERRIDE; protected: - // NOTE: In Java, these are stored as array pointers. In C++, the NumberStringBuilder is stored by + // NOTE: In Java, these are stored as array pointers. In C++, the FormattedStringBuilder is stored by // value and is treated internally as immutable. - NumberStringBuilder fPrefix; - NumberStringBuilder fSuffix; + FormattedStringBuilder fPrefix; + FormattedStringBuilder fSuffix; bool fOverwrite; bool fStrong; Modifier::Parameters fParameters; @@ -187,19 +187,19 @@ class U_I18N_API CurrencySpacingEnabledModifier : public ConstantMultiFieldModif public: /** Safe code path */ CurrencySpacingEnabledModifier( - const NumberStringBuilder &prefix, - const NumberStringBuilder &suffix, + const FormattedStringBuilder &prefix, + const FormattedStringBuilder &suffix, bool overwrite, bool strong, const DecimalFormatSymbols &symbols, UErrorCode &status); - int32_t apply(NumberStringBuilder &output, int32_t leftIndex, int32_t rightIndex, + int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex, UErrorCode &status) const U_OVERRIDE; /** Unsafe code path */ static int32_t - applyCurrencySpacing(NumberStringBuilder &output, int32_t prefixStart, int32_t prefixLen, + applyCurrencySpacing(FormattedStringBuilder &output, int32_t prefixStart, int32_t prefixLen, int32_t suffixStart, int32_t suffixLen, const DecimalFormatSymbols &symbols, UErrorCode &status); @@ -218,7 +218,7 @@ class U_I18N_API CurrencySpacingEnabledModifier : public ConstantMultiFieldModif }; /** Unsafe code path */ - static int32_t applyCurrencySpacingAffix(NumberStringBuilder &output, int32_t index, EAffix affix, + static int32_t applyCurrencySpacingAffix(FormattedStringBuilder &output, int32_t index, EAffix affix, const DecimalFormatSymbols &symbols, UErrorCode &status); static UnicodeSet @@ -234,7 +234,7 @@ class U_I18N_API EmptyModifier : public Modifier, public UMemory { public: explicit EmptyModifier(bool isStrong) : fStrong(isStrong) {} - int32_t apply(NumberStringBuilder &output, int32_t leftIndex, int32_t rightIndex, + int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex, UErrorCode &status) const U_OVERRIDE { (void)output; (void)leftIndex; @@ -289,7 +289,7 @@ class U_I18N_API AdoptingModifierStore : public ModifierStore, public UMemory { /** * Sets the Modifier with the specified signum and plural form. */ - void adoptModifier(int8_t signum, StandardPlural::Form plural, const Modifier *mod) { + void adoptModifier(Signum signum, StandardPlural::Form plural, const Modifier *mod) { U_ASSERT(mods[getModIndex(signum, plural)] == nullptr); mods[getModIndex(signum, plural)] = mod; } @@ -298,13 +298,13 @@ class U_I18N_API AdoptingModifierStore : public ModifierStore, public UMemory { * Sets the Modifier with the specified signum. * The modifier will apply to all plural forms. */ - void adoptModifierWithoutPlural(int8_t signum, const Modifier *mod) { + void adoptModifierWithoutPlural(Signum signum, const Modifier *mod) { U_ASSERT(mods[getModIndex(signum, DEFAULT_STANDARD_PLURAL)] == nullptr); mods[getModIndex(signum, DEFAULT_STANDARD_PLURAL)] = mod; } /** Returns a reference to the modifier; no ownership change. */ - const Modifier *getModifier(int8_t signum, StandardPlural::Form plural) const U_OVERRIDE { + const Modifier *getModifier(Signum signum, StandardPlural::Form plural) const U_OVERRIDE { const Modifier* modifier = mods[getModIndex(signum, plural)]; if (modifier == nullptr && plural != DEFAULT_STANDARD_PLURAL) { modifier = mods[getModIndex(signum, DEFAULT_STANDARD_PLURAL)]; @@ -313,7 +313,7 @@ class U_I18N_API AdoptingModifierStore : public ModifierStore, public UMemory { } /** Returns a reference to the modifier; no ownership change. */ - const Modifier *getModifierWithoutPlural(int8_t signum) const { + const Modifier *getModifierWithoutPlural(Signum signum) const { return mods[getModIndex(signum, DEFAULT_STANDARD_PLURAL)]; } @@ -321,7 +321,7 @@ class U_I18N_API AdoptingModifierStore : public ModifierStore, public UMemory { // NOTE: mods is zero-initialized (to nullptr) const Modifier *mods[3 * StandardPlural::COUNT] = {}; - inline static int32_t getModIndex(int8_t signum, StandardPlural::Form plural) { + inline static int32_t getModIndex(Signum signum, StandardPlural::Form plural) { U_ASSERT(signum >= -1 && signum <= 1); U_ASSERT(plural >= 0 && plural < StandardPlural::COUNT); return static_cast<int32_t>(plural) * 3 + (signum + 1); diff --git a/deps/icu-small/source/i18n/number_output.cpp b/deps/icu-small/source/i18n/number_output.cpp index 6f4e248204..e2f069139a 100644 --- a/deps/icu-small/source/i18n/number_output.cpp +++ b/deps/icu-small/source/i18n/number_output.cpp @@ -9,6 +9,7 @@ #include "number_utypes.h" #include "util.h" #include "number_decimalquantity.h" +#include "number_decnum.h" U_NAMESPACE_BEGIN namespace number { @@ -20,8 +21,7 @@ UPRV_FORMATTED_VALUE_SUBCLASS_AUTO_IMPL(FormattedNumber) UBool FormattedNumber::nextFieldPosition(FieldPosition& fieldPosition, UErrorCode& status) const { UPRV_FORMATTED_VALUE_METHOD_GUARD(FALSE) - // NOTE: MSVC sometimes complains when implicitly converting between bool and UBool - return fData->getStringRef().nextFieldPosition(fieldPosition, status) ? TRUE : FALSE; + return fData->nextFieldPosition(fieldPosition, status); } void FormattedNumber::getAllFieldPositions(FieldPositionIterator& iterator, UErrorCode& status) const { @@ -29,10 +29,17 @@ void FormattedNumber::getAllFieldPositions(FieldPositionIterator& iterator, UErr getAllFieldPositionsImpl(fpih, status); } +void FormattedNumber::toDecimalNumber(ByteSink& sink, UErrorCode& status) const { + UPRV_FORMATTED_VALUE_METHOD_GUARD(UPRV_NOARG) + impl::DecNum decnum; + fData->quantity.toDecNum(decnum, status); + decnum.toString(sink, status); +} + void FormattedNumber::getAllFieldPositionsImpl(FieldPositionIteratorHandler& fpih, UErrorCode& status) const { UPRV_FORMATTED_VALUE_METHOD_GUARD(UPRV_NOARG) - fData->getStringRef().getAllFieldPositions(fpih, status); + fData->getAllFieldPositions(fpih, status); } void FormattedNumber::getDecimalQuantity(impl::DecimalQuantity& output, UErrorCode& status) const { diff --git a/deps/icu-small/source/i18n/number_padding.cpp b/deps/icu-small/source/i18n/number_padding.cpp index 31684d7208..c68a9875b2 100644 --- a/deps/icu-small/source/i18n/number_padding.cpp +++ b/deps/icu-small/source/i18n/number_padding.cpp @@ -7,7 +7,7 @@ #include "unicode/numberformatter.h" #include "number_types.h" -#include "number_stringbuilder.h" +#include "formatted_string_builder.h" #include "number_decimfmtprops.h" using namespace icu; @@ -17,7 +17,7 @@ using namespace icu::number::impl; namespace { int32_t -addPaddingHelper(UChar32 paddingCp, int32_t requiredPadding, NumberStringBuilder &string, int32_t index, +addPaddingHelper(UChar32 paddingCp, int32_t requiredPadding, FormattedStringBuilder &string, int32_t index, UErrorCode &status) { for (int32_t i = 0; i < requiredPadding; i++) { // TODO: If appending to the end, this will cause actual insertion operations. Improve. @@ -60,7 +60,7 @@ Padder Padder::forProperties(const DecimalFormatProperties& properties) { } int32_t Padder::padAndApply(const Modifier &mod1, const Modifier &mod2, - NumberStringBuilder &string, int32_t leftIndex, int32_t rightIndex, + FormattedStringBuilder &string, int32_t leftIndex, int32_t rightIndex, UErrorCode &status) const { int32_t modLength = mod1.getCodePointCount() + mod2.getCodePointCount(); int32_t requiredPadding = fWidth - modLength - string.codePointCount(); diff --git a/deps/icu-small/source/i18n/number_patternmodifier.cpp b/deps/icu-small/source/i18n/number_patternmodifier.cpp index 75de439f3e..724f5b9741 100644 --- a/deps/icu-small/source/i18n/number_patternmodifier.cpp +++ b/deps/icu-small/source/i18n/number_patternmodifier.cpp @@ -43,7 +43,7 @@ void MutablePatternModifier::setSymbols(const DecimalFormatSymbols* symbols, fRules = rules; } -void MutablePatternModifier::setNumberProperties(int8_t signum, StandardPlural::Form plural) { +void MutablePatternModifier::setNumberProperties(Signum signum, StandardPlural::Form plural) { fSignum = signum; fPlural = plural; } @@ -79,12 +79,12 @@ MutablePatternModifier::createImmutableAndChain(const MicroPropsGenerator* paren if (needsPlurals()) { // Slower path when we require the plural keyword. for (StandardPlural::Form plural : STANDARD_PLURAL_VALUES) { - setNumberProperties(1, plural); - pm->adoptModifier(1, plural, createConstantModifier(status)); - setNumberProperties(0, plural); - pm->adoptModifier(0, plural, createConstantModifier(status)); - setNumberProperties(-1, plural); - pm->adoptModifier(-1, plural, createConstantModifier(status)); + setNumberProperties(SIGNUM_POS, plural); + pm->adoptModifier(SIGNUM_POS, plural, createConstantModifier(status)); + setNumberProperties(SIGNUM_ZERO, plural); + pm->adoptModifier(SIGNUM_ZERO, plural, createConstantModifier(status)); + setNumberProperties(SIGNUM_NEG, plural); + pm->adoptModifier(SIGNUM_NEG, plural, createConstantModifier(status)); } if (U_FAILURE(status)) { delete pm; @@ -93,12 +93,12 @@ MutablePatternModifier::createImmutableAndChain(const MicroPropsGenerator* paren return new ImmutablePatternModifier(pm, fRules, parent); // adopts pm } else { // Faster path when plural keyword is not needed. - setNumberProperties(1, StandardPlural::Form::COUNT); - pm->adoptModifierWithoutPlural(1, createConstantModifier(status)); - setNumberProperties(0, StandardPlural::Form::COUNT); - pm->adoptModifierWithoutPlural(0, createConstantModifier(status)); - setNumberProperties(-1, StandardPlural::Form::COUNT); - pm->adoptModifierWithoutPlural(-1, createConstantModifier(status)); + setNumberProperties(SIGNUM_POS, StandardPlural::Form::COUNT); + pm->adoptModifierWithoutPlural(SIGNUM_POS, createConstantModifier(status)); + setNumberProperties(SIGNUM_ZERO, StandardPlural::Form::COUNT); + pm->adoptModifierWithoutPlural(SIGNUM_ZERO, createConstantModifier(status)); + setNumberProperties(SIGNUM_NEG, StandardPlural::Form::COUNT); + pm->adoptModifierWithoutPlural(SIGNUM_NEG, createConstantModifier(status)); if (U_FAILURE(status)) { delete pm; return nullptr; @@ -108,8 +108,8 @@ MutablePatternModifier::createImmutableAndChain(const MicroPropsGenerator* paren } ConstantMultiFieldModifier* MutablePatternModifier::createConstantModifier(UErrorCode& status) { - NumberStringBuilder a; - NumberStringBuilder b; + FormattedStringBuilder a; + FormattedStringBuilder b; insertPrefix(a, 0, status); insertSuffix(b, 0, status); if (fPatternInfo->hasCurrencySign()) { @@ -140,7 +140,7 @@ void ImmutablePatternModifier::applyToMicros( } } -const Modifier* ImmutablePatternModifier::getModifier(int8_t signum, StandardPlural::Form plural) const { +const Modifier* ImmutablePatternModifier::getModifier(Signum signum, StandardPlural::Form plural) const { if (rules == nullptr) { return pm->getModifierWithoutPlural(signum); } else { @@ -170,7 +170,7 @@ void MutablePatternModifier::processQuantity(DecimalQuantity& fq, MicroProps& mi micros.modMiddle = this; } -int32_t MutablePatternModifier::apply(NumberStringBuilder& output, int32_t leftIndex, int32_t rightIndex, +int32_t MutablePatternModifier::apply(FormattedStringBuilder& output, int32_t leftIndex, int32_t rightIndex, UErrorCode& status) const { // The unsafe code path performs self-mutation, so we need a const_cast. // This method needs to be const because it overrides a const method in the parent class. @@ -248,13 +248,13 @@ bool MutablePatternModifier::semanticallyEquivalent(const Modifier& other) const UPRV_UNREACHABLE; } -int32_t MutablePatternModifier::insertPrefix(NumberStringBuilder& sb, int position, UErrorCode& status) { +int32_t MutablePatternModifier::insertPrefix(FormattedStringBuilder& sb, int position, UErrorCode& status) { prepareAffix(true); int32_t length = AffixUtils::unescape(currentAffix, sb, position, *this, fField, status); return length; } -int32_t MutablePatternModifier::insertSuffix(NumberStringBuilder& sb, int position, UErrorCode& status) { +int32_t MutablePatternModifier::insertSuffix(FormattedStringBuilder& sb, int position, UErrorCode& status) { prepareAffix(false); int32_t length = AffixUtils::unescape(currentAffix, sb, position, *this, fField, status); return length; diff --git a/deps/icu-small/source/i18n/number_patternmodifier.h b/deps/icu-small/source/i18n/number_patternmodifier.h index 27e293b64c..b2c90e0af7 100644 --- a/deps/icu-small/source/i18n/number_patternmodifier.h +++ b/deps/icu-small/source/i18n/number_patternmodifier.h @@ -48,7 +48,7 @@ class U_I18N_API ImmutablePatternModifier : public MicroPropsGenerator, public U void applyToMicros(MicroProps& micros, const DecimalQuantity& quantity, UErrorCode& status) const; - const Modifier* getModifier(int8_t signum, StandardPlural::Form plural) const; + const Modifier* getModifier(Signum signum, StandardPlural::Form plural) const; private: ImmutablePatternModifier(AdoptingModifierStore* pm, const PluralRules* rules, @@ -142,7 +142,7 @@ class U_I18N_API MutablePatternModifier * The plural form of the number, required only if the pattern contains the triple * currency sign, "¤¤¤" (and as indicated by {@link #needsPlurals()}). */ - void setNumberProperties(int8_t signum, StandardPlural::Form plural); + void setNumberProperties(Signum signum, StandardPlural::Form plural); /** * Returns true if the pattern represented by this MurkyModifier requires a plural keyword in order to localize. @@ -184,7 +184,7 @@ class U_I18N_API MutablePatternModifier void processQuantity(DecimalQuantity &, MicroProps µs, UErrorCode &status) const U_OVERRIDE; - int32_t apply(NumberStringBuilder &output, int32_t leftIndex, int32_t rightIndex, + int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex, UErrorCode &status) const U_OVERRIDE; int32_t getPrefixLength() const U_OVERRIDE; @@ -223,7 +223,7 @@ class U_I18N_API MutablePatternModifier const PluralRules *fRules; // Number details (initialized in setNumberProperties) - int8_t fSignum; + Signum fSignum; StandardPlural::Form fPlural; // QuantityChain details (initialized in addToChain) @@ -240,17 +240,17 @@ class U_I18N_API MutablePatternModifier * CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP. * * @param a - * A working NumberStringBuilder object; passed from the outside to prevent the need to create many new + * A working FormattedStringBuilder object; passed from the outside to prevent the need to create many new * instances if this method is called in a loop. * @param b - * Another working NumberStringBuilder object. + * Another working FormattedStringBuilder object. * @return The constant modifier object. */ ConstantMultiFieldModifier *createConstantModifier(UErrorCode &status); - int32_t insertPrefix(NumberStringBuilder &sb, int position, UErrorCode &status); + int32_t insertPrefix(FormattedStringBuilder &sb, int position, UErrorCode &status); - int32_t insertSuffix(NumberStringBuilder &sb, int position, UErrorCode &status); + int32_t insertSuffix(FormattedStringBuilder &sb, int position, UErrorCode &status); void prepareAffix(bool isPrefix); }; diff --git a/deps/icu-small/source/i18n/number_patternstring.cpp b/deps/icu-small/source/i18n/number_patternstring.cpp index 9075424663..c7212c1e5c 100644 --- a/deps/icu-small/source/i18n/number_patternstring.cpp +++ b/deps/icu-small/source/i18n/number_patternstring.cpp @@ -352,7 +352,7 @@ void ParsedPatternInfo::consumeIntegerFormat(UErrorCode& status) { result.groupingSizes += 1; result.integerNumerals += 1; result.integerTotal += 1; - if (!result.rounding.isZero() || state.peek() != u'0') { + if (!result.rounding.isZeroish() || state.peek() != u'0') { result.rounding.appendDigit(static_cast<int8_t>(state.peek() - u'0'), 0, true); } break; @@ -532,7 +532,7 @@ PatternParser::patternInfoToProperties(DecimalFormatProperties& properties, Pars properties.roundingIncrement = 0.0; properties.minimumSignificantDigits = positive.integerAtSigns; properties.maximumSignificantDigits = positive.integerAtSigns + positive.integerTrailingHashSigns; - } else if (!positive.rounding.isZero()) { + } else if (!positive.rounding.isZeroish()) { if (!ignoreRounding) { properties.minimumFractionDigits = minFrac; properties.maximumFractionDigits = positive.fractionTotal; @@ -1000,7 +1000,7 @@ PatternStringUtils::convertLocalized(const UnicodeString& input, const DecimalFo } void PatternStringUtils::patternInfoToStringBuilder(const AffixPatternProvider& patternInfo, bool isPrefix, - int8_t signum, UNumberSignDisplay signDisplay, + Signum signum, UNumberSignDisplay signDisplay, StandardPlural::Form plural, bool perMilleReplacesPercent, UnicodeString& output) { @@ -1014,6 +1014,7 @@ void PatternStringUtils::patternInfoToStringBuilder(const AffixPatternProvider& // Should we use the affix from the negative subpattern? (If not, we will use the positive // subpattern.) + // TODO: Deal with signum bool useNegativeAffixPattern = patternInfo.hasNegativeSubpattern() && ( signum == -1 || (patternInfo.negativeHasMinusSign() && plusReplacesMinusSign)); diff --git a/deps/icu-small/source/i18n/number_patternstring.h b/deps/icu-small/source/i18n/number_patternstring.h index 42e7c39161..819c74d4bd 100644 --- a/deps/icu-small/source/i18n/number_patternstring.h +++ b/deps/icu-small/source/i18n/number_patternstring.h @@ -295,7 +295,7 @@ class U_I18N_API PatternStringUtils { * substitution, and plural forms for CurrencyPluralInfo. */ static void patternInfoToStringBuilder(const AffixPatternProvider& patternInfo, bool isPrefix, - int8_t signum, UNumberSignDisplay signDisplay, + Signum signum, UNumberSignDisplay signDisplay, StandardPlural::Form plural, bool perMilleReplacesPercent, UnicodeString& output); diff --git a/deps/icu-small/source/i18n/number_rounding.cpp b/deps/icu-small/source/i18n/number_rounding.cpp index 9e369f7925..813d4b680d 100644 --- a/deps/icu-small/source/i18n/number_rounding.cpp +++ b/deps/icu-small/source/i18n/number_rounding.cpp @@ -33,7 +33,7 @@ int32_t getRoundingMagnitudeSignificant(const DecimalQuantity &value, int maxSig if (maxSig == -1) { return INT32_MIN; } - int magnitude = value.isZero() ? 0 : value.getMagnitude(); + int magnitude = value.isZeroish() ? 0 : value.getMagnitude(); return magnitude - maxSig + 1; } @@ -45,7 +45,7 @@ int32_t getDisplayMagnitudeFraction(int minFrac) { } int32_t getDisplayMagnitudeSignificant(const DecimalQuantity &value, int minSig) { - int magnitude = value.isZero() ? 0 : value.getMagnitude(); + int magnitude = value.isZeroish() ? 0 : value.getMagnitude(); return magnitude - minSig + 1; } @@ -306,8 +306,8 @@ bool RoundingImpl::isSignificantDigits() const { int32_t RoundingImpl::chooseMultiplierAndApply(impl::DecimalQuantity &input, const impl::MultiplierProducer &producer, UErrorCode &status) { - // Do not call this method with zero. - U_ASSERT(!input.isZero()); + // Do not call this method with zero, NaN, or infinity. + U_ASSERT(!input.isZeroish()); // Perform the first attempt at rounding. int magnitude = input.getMagnitude(); @@ -316,7 +316,7 @@ RoundingImpl::chooseMultiplierAndApply(impl::DecimalQuantity &input, const impl: apply(input, status); // If the number rounded to zero, exit. - if (input.isZero() || U_FAILURE(status)) { + if (input.isZeroish() || U_FAILURE(status)) { return multiplier; } @@ -374,7 +374,7 @@ void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const value.setMinFraction( uprv_max(0, -getDisplayMagnitudeSignificant(value, fPrecision.fUnion.fracSig.fMinSig))); // Make sure that digits are displayed on zero. - if (value.isZero() && fPrecision.fUnion.fracSig.fMinSig > 0) { + if (value.isZeroish() && fPrecision.fUnion.fracSig.fMinSig > 0) { value.setMinInteger(1); } break; @@ -436,7 +436,7 @@ void RoundingImpl::apply(impl::DecimalQuantity &value, UErrorCode& status) const void RoundingImpl::apply(impl::DecimalQuantity &value, int32_t minInt, UErrorCode /*status*/) { // This method is intended for the one specific purpose of helping print "00.000E0". U_ASSERT(isSignificantDigits()); - U_ASSERT(value.isZero()); + U_ASSERT(value.isZeroish()); value.setMinFraction(fPrecision.fUnion.fracSig.fMinSig - minInt); } diff --git a/deps/icu-small/source/i18n/number_scientific.cpp b/deps/icu-small/source/i18n/number_scientific.cpp index 6df07b9cc9..20aa45bff0 100644 --- a/deps/icu-small/source/i18n/number_scientific.cpp +++ b/deps/icu-small/source/i18n/number_scientific.cpp @@ -8,7 +8,7 @@ #include <cstdlib> #include "number_scientific.h" #include "number_utils.h" -#include "number_stringbuilder.h" +#include "formatted_string_builder.h" #include "unicode/unum.h" #include "number_microprops.h" @@ -36,7 +36,7 @@ void ScientificModifier::set(int32_t exponent, const ScientificHandler *handler) fHandler = handler; } -int32_t ScientificModifier::apply(NumberStringBuilder &output, int32_t /*leftIndex*/, int32_t rightIndex, +int32_t ScientificModifier::apply(FormattedStringBuilder &output, int32_t /*leftIndex*/, int32_t rightIndex, UErrorCode &status) const { // FIXME: Localized exponent separator location. int i = rightIndex; @@ -123,9 +123,15 @@ void ScientificHandler::processQuantity(DecimalQuantity &quantity, MicroProps &m fParent->processQuantity(quantity, micros, status); if (U_FAILURE(status)) { return; } + // Do not apply scientific notation to special doubles + if (quantity.isInfinite() || quantity.isNaN()) { + micros.modInner = µs.helpers.emptyStrongModifier; + return; + } + // Treat zero as if it had magnitude 0 int32_t exponent; - if (quantity.isZero()) { + if (quantity.isZeroish()) { if (fSettings.fRequireMinInt && micros.rounder.isSignificantDigits()) { // Show "00.000E0" on pattern "00.000E0" micros.rounder.apply(quantity, fSettings.fEngineeringInterval, status); diff --git a/deps/icu-small/source/i18n/number_scientific.h b/deps/icu-small/source/i18n/number_scientific.h index e377bd941e..1c9ce1efa8 100644 --- a/deps/icu-small/source/i18n/number_scientific.h +++ b/deps/icu-small/source/i18n/number_scientific.h @@ -21,7 +21,7 @@ class U_I18N_API ScientificModifier : public UMemory, public Modifier { void set(int32_t exponent, const ScientificHandler *handler); - int32_t apply(NumberStringBuilder &output, int32_t leftIndex, int32_t rightIndex, + int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex, UErrorCode &status) const U_OVERRIDE; int32_t getPrefixLength() const U_OVERRIDE; diff --git a/deps/icu-small/source/i18n/number_skeletons.cpp b/deps/icu-small/source/i18n/number_skeletons.cpp index 4c280ad11d..4025539239 100644 --- a/deps/icu-small/source/i18n/number_skeletons.cpp +++ b/deps/icu-small/source/i18n/number_skeletons.cpp @@ -20,6 +20,7 @@ #include "unicode/numberformatter.h" #include "uinvchar.h" #include "charstr.h" +#include "string_segment.h" using namespace icu; using namespace icu::number; @@ -119,17 +120,17 @@ inline void appendMultiple(UnicodeString& sb, UChar32 cp, int32_t count) { #define CHECK_NULL(seen, field, status) (void)(seen); /* for auto-format line wrapping */ \ -{ \ +UPRV_BLOCK_MACRO_BEGIN { \ if ((seen).field) { \ (status) = U_NUMBER_SKELETON_SYNTAX_ERROR; \ return STATE_NULL; \ } \ (seen).field = true; \ -} +} UPRV_BLOCK_MACRO_END #define SKELETON_UCHAR_TO_CHAR(dest, src, start, end, status) (void)(dest); \ -{ \ +UPRV_BLOCK_MACRO_BEGIN { \ UErrorCode conversionStatus = U_ZERO_ERROR; \ (dest).appendInvariantChars({FALSE, (src).getBuffer() + (start), (end) - (start)}, conversionStatus); \ if (conversionStatus == U_INVARIANT_CONVERSION_ERROR) { \ @@ -140,7 +141,7 @@ inline void appendMultiple(UnicodeString& sb, UChar32 cp, int32_t count) { (status) = conversionStatus; \ return; \ } \ -} +} UPRV_BLOCK_MACRO_END } // anonymous namespace @@ -1217,7 +1218,7 @@ void blueprint_helpers::parseIntegerWidthOption(const StringSegment& segment, Ma maxInt = 0; } for (; offset < segment.length(); offset++) { - if (segment.charAt(offset) == u'#') { + if (maxInt != -1 && segment.charAt(offset) == u'#') { maxInt++; } else { break; diff --git a/deps/icu-small/source/i18n/number_skeletons.h b/deps/icu-small/source/i18n/number_skeletons.h index bc228bd0d7..59af771928 100644 --- a/deps/icu-small/source/i18n/number_skeletons.h +++ b/deps/icu-small/source/i18n/number_skeletons.h @@ -10,10 +10,10 @@ #include "number_types.h" #include "numparse_types.h" #include "unicode/ucharstrie.h" +#include "string_segment.h" -using icu::numparse::impl::StringSegment; - -U_NAMESPACE_BEGIN namespace number { +U_NAMESPACE_BEGIN +namespace number { namespace impl { // Forward-declaration diff --git a/deps/icu-small/source/i18n/number_stringbuilder.h b/deps/icu-small/source/i18n/number_stringbuilder.h deleted file mode 100644 index d48f6e106c..0000000000 --- a/deps/icu-small/source/i18n/number_stringbuilder.h +++ /dev/null @@ -1,164 +0,0 @@ -// © 2017 and later: Unicode, Inc. and others. -// License & terms of use: http://www.unicode.org/copyright.html - -#include "unicode/utypes.h" - -#if !UCONFIG_NO_FORMATTING -#ifndef __NUMBER_STRINGBUILDER_H__ -#define __NUMBER_STRINGBUILDER_H__ - - -#include <cstdint> -#include "unicode/numfmt.h" -#include "unicode/ustring.h" -#include "cstring.h" -#include "uassert.h" -#include "number_types.h" -#include "fphdlimp.h" - -U_NAMESPACE_BEGIN namespace number { -namespace impl { - -class U_I18N_API NumberStringBuilder : public UMemory { - private: - static const int32_t DEFAULT_CAPACITY = 40; - - template<typename T> - union ValueOrHeapArray { - T value[DEFAULT_CAPACITY]; - struct { - T *ptr; - int32_t capacity; - } heap; - }; - - public: - NumberStringBuilder(); - - ~NumberStringBuilder(); - - NumberStringBuilder(const NumberStringBuilder &other); - - NumberStringBuilder &operator=(const NumberStringBuilder &other); - - int32_t length() const; - - int32_t codePointCount() const; - - inline char16_t charAt(int32_t index) const { - U_ASSERT(index >= 0); - U_ASSERT(index < fLength); - return getCharPtr()[fZero + index]; - } - - inline Field fieldAt(int32_t index) const { - U_ASSERT(index >= 0); - U_ASSERT(index < fLength); - return getFieldPtr()[fZero + index]; - } - - UChar32 getFirstCodePoint() const; - - UChar32 getLastCodePoint() const; - - UChar32 codePointAt(int32_t index) const; - - UChar32 codePointBefore(int32_t index) const; - - NumberStringBuilder &clear(); - - int32_t appendCodePoint(UChar32 codePoint, Field field, UErrorCode &status); - - int32_t insertCodePoint(int32_t index, UChar32 codePoint, Field field, UErrorCode &status); - - int32_t append(const UnicodeString &unistr, Field field, UErrorCode &status); - - int32_t insert(int32_t index, const UnicodeString &unistr, Field field, UErrorCode &status); - - int32_t insert(int32_t index, const UnicodeString &unistr, int32_t start, int32_t end, Field field, - UErrorCode &status); - - int32_t splice(int32_t startThis, int32_t endThis, const UnicodeString &unistr, - int32_t startOther, int32_t endOther, Field field, UErrorCode& status); - - int32_t append(const NumberStringBuilder &other, UErrorCode &status); - - int32_t insert(int32_t index, const NumberStringBuilder &other, UErrorCode &status); - - void writeTerminator(UErrorCode& status); - - /** - * Gets a "safe" UnicodeString that can be used even after the NumberStringBuilder is destructed. - * */ - UnicodeString toUnicodeString() const; - - /** - * Gets an "unsafe" UnicodeString that is valid only as long as the NumberStringBuilder is alive and - * unchanged. Slightly faster than toUnicodeString(). - */ - const UnicodeString toTempUnicodeString() const; - - UnicodeString toDebugString() const; - - const char16_t *chars() const; - - bool contentEquals(const NumberStringBuilder &other) const; - - bool nextFieldPosition(FieldPosition& fp, UErrorCode& status) const; - - void getAllFieldPositions(FieldPositionIteratorHandler& fpih, UErrorCode& status) const; - - bool nextPosition(ConstrainedFieldPosition& cfpos, Field numericField, UErrorCode& status) const; - - bool containsField(Field field) const; - - private: - bool fUsingHeap = false; - ValueOrHeapArray<char16_t> fChars; - ValueOrHeapArray<Field> fFields; - int32_t fZero = DEFAULT_CAPACITY / 2; - int32_t fLength = 0; - - inline char16_t *getCharPtr() { - return fUsingHeap ? fChars.heap.ptr : fChars.value; - } - - inline const char16_t *getCharPtr() const { - return fUsingHeap ? fChars.heap.ptr : fChars.value; - } - - inline Field *getFieldPtr() { - return fUsingHeap ? fFields.heap.ptr : fFields.value; - } - - inline const Field *getFieldPtr() const { - return fUsingHeap ? fFields.heap.ptr : fFields.value; - } - - inline int32_t getCapacity() const { - return fUsingHeap ? fChars.heap.capacity : DEFAULT_CAPACITY; - } - - int32_t prepareForInsert(int32_t index, int32_t count, UErrorCode &status); - - int32_t prepareForInsertHelper(int32_t index, int32_t count, UErrorCode &status); - - int32_t remove(int32_t index, int32_t count); - - static bool isIntOrGroup(Field field); - - static bool isNumericField(Field field); - - int32_t trimBack(int32_t limit) const; - - int32_t trimFront(int32_t start) const; -}; - -} // namespace impl -} // namespace number -U_NAMESPACE_END - - -#endif //__NUMBER_STRINGBUILDER_H__ - -#endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/number_types.h b/deps/icu-small/source/i18n/number_types.h index 225d1e5775..d62aa6a66b 100644 --- a/deps/icu-small/source/i18n/number_types.h +++ b/deps/icu-small/source/i18n/number_types.h @@ -17,17 +17,16 @@ #include "unicode/platform.h" #include "unicode/uniset.h" #include "standardplural.h" +#include "formatted_string_builder.h" -U_NAMESPACE_BEGIN namespace number { +U_NAMESPACE_BEGIN +namespace number { namespace impl { -// Typedef several enums for brevity and for easier comparison to Java. +// For convenience and historical reasons, import the Field typedef to the namespace. +typedef FormattedStringBuilder::Field Field; -// Convention: bottom 4 bits for field, top 4 bits for field category. -// Field category 0 implies the number category so that the number field -// literals can be directly passed as a Field type. -// See the helper functions in "NumFieldUtils" in number_utils.h -typedef uint8_t Field; +// Typedef several enums for brevity and for easier comparison to Java. typedef UNumberFormatRoundingMode RoundingMode; @@ -49,7 +48,6 @@ static constexpr char16_t kFallbackPaddingString[] = u" "; class Modifier; class MutablePatternModifier; class DecimalQuantity; -class NumberStringBuilder; class ModifierStore; struct MicroProps; @@ -93,6 +91,12 @@ enum CompactType { TYPE_DECIMAL, TYPE_CURRENCY }; +enum Signum { + SIGNUM_NEG = -1, + SIGNUM_ZERO = 0, + SIGNUM_POS = 1 +}; + class U_I18N_API AffixPatternProvider { public: @@ -160,7 +164,7 @@ class U_I18N_API Modifier { * formatted. * @return The number of characters (UTF-16 code units) that were added to the string builder. */ - virtual int32_t apply(NumberStringBuilder& output, int leftIndex, int rightIndex, + virtual int32_t apply(FormattedStringBuilder& output, int leftIndex, int rightIndex, UErrorCode& status) const = 0; /** @@ -196,11 +200,11 @@ class U_I18N_API Modifier { */ struct U_I18N_API Parameters { const ModifierStore* obj = nullptr; - int8_t signum; + Signum signum; StandardPlural::Form plural; Parameters(); - Parameters(const ModifierStore* _obj, int8_t _signum, StandardPlural::Form _plural); + Parameters(const ModifierStore* _obj, Signum _signum, StandardPlural::Form _plural); }; /** @@ -231,7 +235,7 @@ class U_I18N_API ModifierStore { /** * Returns a Modifier with the given parameters (best-effort). */ - virtual const Modifier* getModifier(int8_t signum, StandardPlural::Form plural) const = 0; + virtual const Modifier* getModifier(Signum signum, StandardPlural::Form plural) const = 0; }; diff --git a/deps/icu-small/source/i18n/number_utils.cpp b/deps/icu-small/source/i18n/number_utils.cpp index 0983b7b072..91d7f335cd 100644 --- a/deps/icu-small/source/i18n/number_utils.cpp +++ b/deps/icu-small/source/i18n/number_utils.cpp @@ -252,4 +252,15 @@ bool DecNum::isZero() const { return decNumberIsZero(fData.getAlias()); } +void DecNum::toString(ByteSink& output, UErrorCode& status) const { + if (U_FAILURE(status)) { + return; + } + // "string must be at least dn->digits+14 characters long" + int32_t minCapacity = fData.getAlias()->digits + 14; + MaybeStackArray<char, 30> buffer(minCapacity); + uprv_decNumberToString(fData, buffer.getAlias()); + output.Append(buffer.getAlias(), static_cast<int32_t>(uprv_strlen(buffer.getAlias()))); +} + #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/number_utils.h b/deps/icu-small/source/i18n/number_utils.h index 203dec6d83..93195f080b 100644 --- a/deps/icu-small/source/i18n/number_utils.h +++ b/deps/icu-small/source/i18n/number_utils.h @@ -17,6 +17,7 @@ #include "number_roundingutils.h" #include "decNumber.h" #include "charstr.h" +#include "formatted_string_builder.h" U_NAMESPACE_BEGIN @@ -32,52 +33,10 @@ enum CldrPatternStyle { CLDR_PATTERN_STYLE_COUNT, }; - -/** - * Helper functions for dealing with the Field typedef, which stores fields - * in a compressed format. - */ -class NumFieldUtils { -public: - struct CategoryFieldPair { - int32_t category; - int32_t field; - }; - - /** Compile-time function to construct a Field from a category and a field */ - template <int32_t category, int32_t field> - static constexpr Field compress() { - static_assert(category != 0, "cannot use Undefined category in NumFieldUtils"); - static_assert(category <= 0xf, "only 4 bits for category"); - static_assert(field <= 0xf, "only 4 bits for field"); - return static_cast<int8_t>((category << 4) | field); - } - - /** Runtime inline function to unpack the category and field from the Field */ - static inline CategoryFieldPair expand(Field field) { - if (field == UNUM_FIELD_COUNT) { - return {UFIELD_CATEGORY_UNDEFINED, 0}; - } - CategoryFieldPair ret = { - (field >> 4), - (field & 0xf) - }; - if (ret.category == 0) { - ret.category = UFIELD_CATEGORY_NUMBER; - } - return ret; - } - - static inline bool isNumericField(Field field) { - int8_t category = field >> 4; - return category == 0 || category == UFIELD_CATEGORY_NUMBER; - } -}; - // Namespace for naked functions namespace utils { -inline int32_t insertDigitFromSymbols(NumberStringBuilder& output, int32_t index, int8_t digit, +inline int32_t insertDigitFromSymbols(FormattedStringBuilder& output, int32_t index, int8_t digit, const DecimalFormatSymbols& symbols, Field field, UErrorCode& status) { if (symbols.getCodePointZero() != -1) { diff --git a/deps/icu-small/source/i18n/number_utypes.h b/deps/icu-small/source/i18n/number_utypes.h index 88b493cbc2..6dbe5bee68 100644 --- a/deps/icu-small/source/i18n/number_utypes.h +++ b/deps/icu-small/source/i18n/number_utypes.h @@ -10,7 +10,7 @@ #include "unicode/numberformatter.h" #include "number_types.h" #include "number_decimalquantity.h" -#include "number_stringbuilder.h" +#include "formatted_string_builder.h" #include "formattedval_impl.h" U_NAMESPACE_BEGIN namespace number { @@ -31,9 +31,9 @@ const DecimalQuantity* validateUFormattedNumberToDecimalQuantity( * The DecimalQuantity is not currently being used by FormattedNumber, but at some point it could be used * to add a toDecNumber() or similar method. */ -class UFormattedNumberData : public FormattedValueNumberStringBuilderImpl { +class UFormattedNumberData : public FormattedValueStringBuilderImpl { public: - UFormattedNumberData() : FormattedValueNumberStringBuilderImpl(0) {} + UFormattedNumberData() : FormattedValueStringBuilderImpl(0) {} virtual ~UFormattedNumberData(); DecimalQuantity quantity; diff --git a/deps/icu-small/source/i18n/numfmt.cpp b/deps/icu-small/source/i18n/numfmt.cpp index 21efd18455..bf78179bcd 100644 --- a/deps/icu-small/source/i18n/numfmt.cpp +++ b/deps/icu-small/source/i18n/numfmt.cpp @@ -569,7 +569,7 @@ NumberFormat::format(const Formattable& obj, if(arg.wasCurrency() && u_strcmp(iso, getCurrency())) { // trying to format a different currency. // Right now, we clone. - LocalPointer<NumberFormat> cloneFmt((NumberFormat*)this->clone()); + LocalPointer<NumberFormat> cloneFmt(this->clone()); cloneFmt->setCurrency(iso, status); // next line should NOT recurse, because n is numeric whereas obj was a wrapper around currency amount. return cloneFmt->format(*n, appendTo, pos, status); @@ -624,7 +624,7 @@ NumberFormat::format(const Formattable& obj, if(arg.wasCurrency() && u_strcmp(iso, getCurrency())) { // trying to format a different currency. // Right now, we clone. - LocalPointer<NumberFormat> cloneFmt((NumberFormat*)this->clone()); + LocalPointer<NumberFormat> cloneFmt(this->clone()); cloneFmt->setCurrency(iso, status); // next line should NOT recurse, because n is numeric whereas obj was a wrapper around currency amount. return cloneFmt->format(*n, appendTo, posIter, status); @@ -986,15 +986,19 @@ static UBool haveService() { URegistryKey U_EXPORT2 NumberFormat::registerFactory(NumberFormatFactory* toAdopt, UErrorCode& status) { - ICULocaleService *service = getNumberFormatService(); - if (service) { - NFFactory *tempnnf = new NFFactory(toAdopt); - if (tempnnf != NULL) { - return service->registerFactory(tempnnf, status); - } - } - status = U_MEMORY_ALLOCATION_ERROR; - return NULL; + if (U_FAILURE(status)) { + delete toAdopt; + return nullptr; + } + ICULocaleService *service = getNumberFormatService(); + if (service) { + NFFactory *tempnnf = new NFFactory(toAdopt); + if (tempnnf != NULL) { + return service->registerFactory(tempnnf, status); + } + } + status = U_MEMORY_ALLOCATION_ERROR; + return NULL; } // ------------------------------------- @@ -1055,7 +1059,7 @@ NumberFormat::createInstance(const Locale& loc, UNumberFormatStyle kind, UErrorC if (U_FAILURE(status)) { return NULL; } - NumberFormat *result = static_cast<NumberFormat *>((*shared)->clone()); + NumberFormat *result = (*shared)->clone(); shared->removeRef(); if (result == NULL) { status = U_MEMORY_ALLOCATION_ERROR; @@ -1362,7 +1366,7 @@ NumberFormat::makeInstance(const Locale& desiredLocale, // TODO: Bad hash key usage, see ticket #8504. int32_t hashKey = desiredLocale.hashCode(); - static icu::UMutex nscacheMutex = U_MUTEX_INITIALIZER; + static UMutex nscacheMutex; Mutex lock(&nscacheMutex); ns = (NumberingSystem *)uhash_iget(NumberingSystem_cache, hashKey); if (ns == NULL) { diff --git a/deps/icu-small/source/i18n/numparse_affixes.cpp b/deps/icu-small/source/i18n/numparse_affixes.cpp index 12543a641b..4f83e0dd40 100644 --- a/deps/icu-small/source/i18n/numparse_affixes.cpp +++ b/deps/icu-small/source/i18n/numparse_affixes.cpp @@ -13,6 +13,7 @@ #include "numparse_affixes.h" #include "numparse_utils.h" #include "number_utils.h" +#include "string_segment.h" using namespace icu; using namespace icu::numparse; @@ -280,7 +281,9 @@ void AffixMatcherWarehouse::createAffixMatchers(const AffixPatternProvider& patt AffixPatternMatcher* posSuffix = nullptr; // Pre-process the affix strings to resolve LDML rules like sign display. - for (int8_t signum = 1; signum >= -1; signum--) { + for (int8_t signumInt = 1; signumInt >= -1; signumInt--) { + auto signum = static_cast<Signum>(signumInt); + // Generate Prefix bool hasPrefix = false; PatternStringUtils::patternInfoToStringBuilder( diff --git a/deps/icu-small/source/i18n/numparse_compositions.cpp b/deps/icu-small/source/i18n/numparse_compositions.cpp index 19253da805..2f7e1ab28d 100644 --- a/deps/icu-small/source/i18n/numparse_compositions.cpp +++ b/deps/icu-small/source/i18n/numparse_compositions.cpp @@ -11,6 +11,7 @@ #include "numparse_types.h" #include "numparse_compositions.h" +#include "string_segment.h" #include "unicode/uniset.h" using namespace icu; diff --git a/deps/icu-small/source/i18n/numparse_currency.cpp b/deps/icu-small/source/i18n/numparse_currency.cpp index 598ace5653..6b53a73edf 100644 --- a/deps/icu-small/source/i18n/numparse_currency.cpp +++ b/deps/icu-small/source/i18n/numparse_currency.cpp @@ -14,6 +14,7 @@ #include "ucurrimp.h" #include "unicode/errorcode.h" #include "numparse_utils.h" +#include "string_segment.h" using namespace icu; using namespace icu::numparse; diff --git a/deps/icu-small/source/i18n/numparse_decimal.cpp b/deps/icu-small/source/i18n/numparse_decimal.cpp index b120c5c6ad..cf1e815672 100644 --- a/deps/icu-small/source/i18n/numparse_decimal.cpp +++ b/deps/icu-small/source/i18n/numparse_decimal.cpp @@ -16,6 +16,7 @@ #include "unicode/uchar.h" #include "putilimp.h" #include "number_decimalquantity.h" +#include "string_segment.h" using namespace icu; using namespace icu::numparse; diff --git a/deps/icu-small/source/i18n/numparse_impl.cpp b/deps/icu-small/source/i18n/numparse_impl.cpp index 412ea89c86..bf5829061a 100644 --- a/deps/icu-small/source/i18n/numparse_impl.cpp +++ b/deps/icu-small/source/i18n/numparse_impl.cpp @@ -39,7 +39,7 @@ NumberParserImpl::createSimpleParser(const Locale& locale, const UnicodeString& LocalPointer<NumberParserImpl> parser(new NumberParserImpl(parseFlags)); DecimalFormatSymbols symbols(locale, status); - parser->fLocalMatchers.ignorables = {unisets::DEFAULT_IGNORABLES}; + parser->fLocalMatchers.ignorables = {parseFlags}; IgnorablesMatcher& ignorables = parser->fLocalMatchers.ignorables; DecimalFormatSymbols dfs(locale, status); @@ -114,6 +114,7 @@ NumberParserImpl::createParserFromProperties(const number::impl::DecimalFormatPr parseFlags |= PARSE_FLAG_STRICT_SEPARATORS; parseFlags |= PARSE_FLAG_USE_FULL_AFFIXES; parseFlags |= PARSE_FLAG_EXACT_AFFIX; + parseFlags |= PARSE_FLAG_STRICT_IGNORABLES; } else { parseFlags |= PARSE_FLAG_INCLUDE_UNPAIRED_AFFIXES; } @@ -129,8 +130,7 @@ NumberParserImpl::createParserFromProperties(const number::impl::DecimalFormatPr LocalPointer<NumberParserImpl> parser(new NumberParserImpl(parseFlags)); - parser->fLocalMatchers.ignorables = { - isStrict ? unisets::STRICT_IGNORABLES : unisets::DEFAULT_IGNORABLES}; + parser->fLocalMatchers.ignorables = {parseFlags}; IgnorablesMatcher& ignorables = parser->fLocalMatchers.ignorables; ////////////////////// diff --git a/deps/icu-small/source/i18n/numparse_impl.h b/deps/icu-small/source/i18n/numparse_impl.h index 7d5f0b6f0b..380d9aa4c6 100644 --- a/deps/icu-small/source/i18n/numparse_impl.h +++ b/deps/icu-small/source/i18n/numparse_impl.h @@ -18,6 +18,7 @@ #include "unicode/localpointer.h" #include "numparse_validators.h" #include "number_multiplier.h" +#include "string_segment.h" U_NAMESPACE_BEGIN diff --git a/deps/icu-small/source/i18n/numparse_parsednumber.cpp b/deps/icu-small/source/i18n/numparse_parsednumber.cpp index 3145f718dc..4b373a3c31 100644 --- a/deps/icu-small/source/i18n/numparse_parsednumber.cpp +++ b/deps/icu-small/source/i18n/numparse_parsednumber.cpp @@ -11,6 +11,7 @@ #include "numparse_types.h" #include "number_decimalquantity.h" +#include "string_segment.h" #include "putilimp.h" #include <cmath> @@ -73,7 +74,7 @@ double ParsedNumber::getDouble(UErrorCode& status) const { status = U_INVALID_STATE_ERROR; return 0.0; } - if (quantity.isZero() && quantity.isNegative()) { + if (quantity.isZeroish() && quantity.isNegative()) { return -0.0; } @@ -106,7 +107,7 @@ void ParsedNumber::populateFormattable(Formattable& output, parse_flags_t parseF } } U_ASSERT(!quantity.bogus); - if (quantity.isZero() && quantity.isNegative() && !integerOnly) { + if (quantity.isZeroish() && quantity.isNegative() && !integerOnly) { output.setDouble(-0.0); return; } diff --git a/deps/icu-small/source/i18n/numparse_scientific.cpp b/deps/icu-small/source/i18n/numparse_scientific.cpp index de38957440..4b88cd998f 100644 --- a/deps/icu-small/source/i18n/numparse_scientific.cpp +++ b/deps/icu-small/source/i18n/numparse_scientific.cpp @@ -12,6 +12,7 @@ #include "numparse_types.h" #include "numparse_scientific.h" #include "static_unicode_sets.h" +#include "string_segment.h" using namespace icu; using namespace icu::numparse; @@ -33,7 +34,8 @@ inline const UnicodeSet& plusSignSet() { ScientificMatcher::ScientificMatcher(const DecimalFormatSymbols& dfs, const Grouper& grouper) : fExponentSeparatorString(dfs.getConstSymbol(DecimalFormatSymbols::kExponentialSymbol)), - fExponentMatcher(dfs, grouper, PARSE_FLAG_INTEGER_ONLY | PARSE_FLAG_GROUPING_DISABLED) { + fExponentMatcher(dfs, grouper, PARSE_FLAG_INTEGER_ONLY | PARSE_FLAG_GROUPING_DISABLED), + fIgnorablesMatcher(PARSE_FLAG_STRICT_IGNORABLES) { const UnicodeString& minusSign = dfs.getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); if (minusSignSet().contains(minusSign)) { @@ -63,15 +65,25 @@ bool ScientificMatcher::match(StringSegment& segment, ParsedNumber& result, UErr // First match the scientific separator, and then match another number after it. // NOTE: This is guarded by the smoke test; no need to check fExponentSeparatorString length again. - int overlap1 = segment.getCommonPrefixLength(fExponentSeparatorString); - if (overlap1 == fExponentSeparatorString.length()) { + int32_t initialOffset = segment.getOffset(); + int32_t overlap = segment.getCommonPrefixLength(fExponentSeparatorString); + if (overlap == fExponentSeparatorString.length()) { // Full exponent separator match. // First attempt to get a code point, returning true if we can't get one. - if (segment.length() == overlap1) { + if (segment.length() == overlap) { + return true; + } + segment.adjustOffset(overlap); + + // Allow ignorables before the sign. + // Note: call site is guarded by the segment.length() check above. + // Note: the ignorables matcher should not touch the result. + fIgnorablesMatcher.match(segment, result, status); + if (segment.length() == 0) { + segment.setOffset(initialOffset); return true; } - segment.adjustOffset(overlap1); // Allow a sign, and then try to match digits. int8_t exponentSign = 1; @@ -81,24 +93,37 @@ bool ScientificMatcher::match(StringSegment& segment, ParsedNumber& result, UErr } else if (segment.startsWith(plusSignSet())) { segment.adjustOffsetByCodePoint(); } else if (segment.startsWith(fCustomMinusSign)) { - // Note: call site is guarded with startsWith, which returns false on empty string - int32_t overlap2 = segment.getCommonPrefixLength(fCustomMinusSign); - if (overlap2 != fCustomMinusSign.length()) { - // Partial custom sign match; un-match the exponent separator. - segment.adjustOffset(-overlap1); + overlap = segment.getCommonPrefixLength(fCustomMinusSign); + if (overlap != fCustomMinusSign.length()) { + // Partial custom sign match + segment.setOffset(initialOffset); return true; } exponentSign = -1; - segment.adjustOffset(overlap2); + segment.adjustOffset(overlap); } else if (segment.startsWith(fCustomPlusSign)) { - // Note: call site is guarded with startsWith, which returns false on empty string - int32_t overlap2 = segment.getCommonPrefixLength(fCustomPlusSign); - if (overlap2 != fCustomPlusSign.length()) { - // Partial custom sign match; un-match the exponent separator. - segment.adjustOffset(-overlap1); + overlap = segment.getCommonPrefixLength(fCustomPlusSign); + if (overlap != fCustomPlusSign.length()) { + // Partial custom sign match + segment.setOffset(initialOffset); return true; } - segment.adjustOffset(overlap2); + segment.adjustOffset(overlap); + } + + // Return true if the segment is empty. + if (segment.length() == 0) { + segment.setOffset(initialOffset); + return true; + } + + // Allow ignorables after the sign. + // Note: call site is guarded by the segment.length() check above. + // Note: the ignorables matcher should not touch the result. + fIgnorablesMatcher.match(segment, result, status); + if (segment.length() == 0) { + segment.setOffset(initialOffset); + return true; } // We are supposed to accept E0 after NaN, so we need to make sure result.quantity is available. @@ -112,12 +137,12 @@ bool ScientificMatcher::match(StringSegment& segment, ParsedNumber& result, UErr // At least one exponent digit was matched. result.flags |= FLAG_HAS_EXPONENT; } else { - // No exponent digits were matched; un-match the exponent separator. - segment.adjustOffset(-overlap1); + // No exponent digits were matched + segment.setOffset(initialOffset); } return digitsReturnValue; - } else if (overlap1 == segment.length()) { + } else if (overlap == segment.length()) { // Partial exponent separator match return true; } diff --git a/deps/icu-small/source/i18n/numparse_scientific.h b/deps/icu-small/source/i18n/numparse_scientific.h index ddecf858af..5617c0c6a6 100644 --- a/deps/icu-small/source/i18n/numparse_scientific.h +++ b/deps/icu-small/source/i18n/numparse_scientific.h @@ -9,6 +9,7 @@ #include "numparse_types.h" #include "numparse_decimal.h" +#include "numparse_symbols.h" #include "unicode/numberformatter.h" using icu::number::impl::Grouper; @@ -32,6 +33,7 @@ class ScientificMatcher : public NumberParseMatcher, public UMemory { private: UnicodeString fExponentSeparatorString; DecimalMatcher fExponentMatcher; + IgnorablesMatcher fIgnorablesMatcher; UnicodeString fCustomMinusSign; UnicodeString fCustomPlusSign; }; diff --git a/deps/icu-small/source/i18n/numparse_stringsegment.h b/deps/icu-small/source/i18n/numparse_stringsegment.h deleted file mode 100644 index 7a84444d41..0000000000 --- a/deps/icu-small/source/i18n/numparse_stringsegment.h +++ /dev/null @@ -1,24 +0,0 @@ -// © 2018 and later: Unicode, Inc. and others. -// License & terms of use: http://www.unicode.org/copyright.html - -#include "unicode/utypes.h" - -#if !UCONFIG_NO_FORMATTING -#ifndef __NUMPARSE_STRINGSEGMENT_H__ -#define __NUMPARSE_STRINGSEGMENT_H__ - -#include "numparse_types.h" -#include "number_types.h" -#include "unicode/unistr.h" - -U_NAMESPACE_BEGIN -namespace numparse { -namespace impl { - - -} // namespace impl -} // namespace numparse -U_NAMESPACE_END - -#endif //__NUMPARSE_STRINGSEGMENT_H__ -#endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/numparse_symbols.cpp b/deps/icu-small/source/i18n/numparse_symbols.cpp index e0daab9374..608f4f5c8b 100644 --- a/deps/icu-small/source/i18n/numparse_symbols.cpp +++ b/deps/icu-small/source/i18n/numparse_symbols.cpp @@ -12,6 +12,7 @@ #include "numparse_types.h" #include "numparse_symbols.h" #include "numparse_utils.h" +#include "string_segment.h" using namespace icu; using namespace icu::numparse; @@ -68,8 +69,12 @@ UnicodeString SymbolMatcher::toString() const { } -IgnorablesMatcher::IgnorablesMatcher(unisets::Key key) - : SymbolMatcher({}, key) { +IgnorablesMatcher::IgnorablesMatcher(parse_flags_t parseFlags) : + SymbolMatcher( + {}, + (0 != (parseFlags & PARSE_FLAG_STRICT_IGNORABLES)) ? + unisets::STRICT_IGNORABLES : + unisets::DEFAULT_IGNORABLES) { } bool IgnorablesMatcher::isFlexible() const { diff --git a/deps/icu-small/source/i18n/numparse_symbols.h b/deps/icu-small/source/i18n/numparse_symbols.h index 8912ee95b0..beb133f7d0 100644 --- a/deps/icu-small/source/i18n/numparse_symbols.h +++ b/deps/icu-small/source/i18n/numparse_symbols.h @@ -50,7 +50,7 @@ class U_I18N_API IgnorablesMatcher : public SymbolMatcher { public: IgnorablesMatcher() = default; // WARNING: Leaves the object in an unusable state - IgnorablesMatcher(unisets::Key key); + IgnorablesMatcher(parse_flags_t parseFlags); bool isFlexible() const override; diff --git a/deps/icu-small/source/i18n/numparse_types.h b/deps/icu-small/source/i18n/numparse_types.h index f837d8d279..b4007c2ff5 100644 --- a/deps/icu-small/source/i18n/numparse_types.h +++ b/deps/icu-small/source/i18n/numparse_types.h @@ -9,12 +9,13 @@ #include "unicode/uobject.h" #include "number_decimalquantity.h" +#include "string_segment.h" -U_NAMESPACE_BEGIN namespace numparse { +U_NAMESPACE_BEGIN +namespace numparse { namespace impl { // Forward-declarations -class StringSegment; class ParsedNumber; typedef int32_t result_flags_t; @@ -50,6 +51,7 @@ enum ParseFlags { // PARSE_FLAG_FORCE_BIG_DECIMAL = 0x1000, // not used in ICU4C PARSE_FLAG_NO_FOREIGN_CURRENCY = 0x2000, PARSE_FLAG_ALLOW_INFINITE_RECURSION = 0x4000, + PARSE_FLAG_STRICT_IGNORABLES = 0x8000, }; @@ -170,115 +172,6 @@ class U_I18N_API ParsedNumber { /** - * A mutable class allowing for a String with a variable offset and length. The charAt, length, and - * subSequence methods all operate relative to the fixed offset into the String. - * - * @author sffc - */ -// Exported as U_I18N_API for tests -class U_I18N_API StringSegment : public UMemory { - public: - StringSegment(const UnicodeString& str, bool ignoreCase); - - int32_t getOffset() const; - - void setOffset(int32_t start); - - /** - * Equivalent to <code>setOffset(getOffset()+delta)</code>. - * - * <p> - * This method is usually called by a Matcher to register that a char was consumed. If the char is - * strong (it usually is, except for things like whitespace), follow this with a call to - * {@link ParsedNumber#setCharsConsumed}. For more information on strong chars, see that method. - */ - void adjustOffset(int32_t delta); - - /** - * Adjusts the offset by the width of the current code point, either 1 or 2 chars. - */ - void adjustOffsetByCodePoint(); - - void setLength(int32_t length); - - void resetLength(); - - int32_t length() const; - - char16_t charAt(int32_t index) const; - - UChar32 codePointAt(int32_t index) const; - - UnicodeString toUnicodeString() const; - - const UnicodeString toTempUnicodeString() const; - - /** - * Returns the first code point in the string segment, or -1 if the string starts with an invalid - * code point. - * - * <p> - * <strong>Important:</strong> Most of the time, you should use {@link #matches}, which handles case - * folding logic, instead of this method. - */ - UChar32 getCodePoint() const; - - /** - * Returns true if the first code point of this StringSegment equals the given code point. - * - * <p> - * This method will perform case folding if case folding is enabled for the parser. - */ - bool startsWith(UChar32 otherCp) const; - - /** - * Returns true if the first code point of this StringSegment is in the given UnicodeSet. - */ - bool startsWith(const UnicodeSet& uniset) const; - - /** - * Returns true if there is at least one code point of overlap between this StringSegment and the - * given UnicodeString. - */ - bool startsWith(const UnicodeString& other) const; - - /** - * Returns the length of the prefix shared by this StringSegment and the given CharSequence. For - * example, if this string segment is "aab", and the char sequence is "aac", this method returns 2, - * since the first 2 characters are the same. - * - * <p> - * This method only returns offsets along code point boundaries. - * - * <p> - * This method will perform case folding if case folding was enabled in the constructor. - * - * <p> - * IMPORTANT: The given UnicodeString must not be empty! It is the caller's responsibility to check. - */ - int32_t getCommonPrefixLength(const UnicodeString& other); - - /** - * Like {@link #getCommonPrefixLength}, but never performs case folding, even if case folding is - * enabled for the parser. - */ - int32_t getCaseSensitivePrefixLength(const UnicodeString& other); - - bool operator==(const UnicodeString& other) const; - - private: - const UnicodeString& fStr; - int32_t fStart; - int32_t fEnd; - bool fFoldCase; - - int32_t getPrefixLengthInternal(const UnicodeString& other, bool foldCase); - - static bool codePointsEqual(UChar32 cp1, UChar32 cp2, bool foldCase); -}; - - -/** * The core interface implemented by all matchers used for number parsing. * * Given a string, there should NOT be more than one way to consume the string with the same matcher diff --git a/deps/icu-small/source/i18n/numrange_fluent.cpp b/deps/icu-small/source/i18n/numrange_fluent.cpp index b284561cdc..654cafaf00 100644 --- a/deps/icu-small/source/i18n/numrange_fluent.cpp +++ b/deps/icu-small/source/i18n/numrange_fluent.cpp @@ -382,7 +382,7 @@ UPRV_FORMATTED_VALUE_SUBCLASS_AUTO_IMPL(FormattedNumberRange) UBool FormattedNumberRange::nextFieldPosition(FieldPosition& fieldPosition, UErrorCode& status) const { UPRV_FORMATTED_VALUE_METHOD_GUARD(FALSE) // NOTE: MSVC sometimes complains when implicitly converting between bool and UBool - return fData->getStringRef().nextFieldPosition(fieldPosition, status) ? TRUE : FALSE; + return fData->nextFieldPosition(fieldPosition, status); } void FormattedNumberRange::getAllFieldPositions(FieldPositionIterator& iterator, UErrorCode& status) const { @@ -393,7 +393,7 @@ void FormattedNumberRange::getAllFieldPositions(FieldPositionIterator& iterator, void FormattedNumberRange::getAllFieldPositionsImpl( FieldPositionIteratorHandler& fpih, UErrorCode& status) const { UPRV_FORMATTED_VALUE_METHOD_GUARD(UPRV_NOARG) - fData->getStringRef().getAllFieldPositions(fpih, status); + fData->getAllFieldPositions(fpih, status); } UnicodeString FormattedNumberRange::getFirstDecimal(UErrorCode& status) const { diff --git a/deps/icu-small/source/i18n/numrange_impl.cpp b/deps/icu-small/source/i18n/numrange_impl.cpp index 05eb2b84de..7d732b31ec 100644 --- a/deps/icu-small/source/i18n/numrange_impl.cpp +++ b/deps/icu-small/source/i18n/numrange_impl.cpp @@ -397,7 +397,7 @@ void NumberRangeFormatterImpl::formatRange(UFormattedNumberRangeData& data, break; } - NumberStringBuilder& string = data.getStringRef(); + FormattedStringBuilder& string = data.getStringRef(); int32_t lengthPrefix = 0; int32_t length1 = 0; int32_t lengthInfix = 0; diff --git a/deps/icu-small/source/i18n/numrange_impl.h b/deps/icu-small/source/i18n/numrange_impl.h index dc25dd4d67..f88e300913 100644 --- a/deps/icu-small/source/i18n/numrange_impl.h +++ b/deps/icu-small/source/i18n/numrange_impl.h @@ -13,7 +13,7 @@ #include "number_types.h" #include "number_decimalquantity.h" #include "number_formatimpl.h" -#include "number_stringbuilder.h" +#include "formatted_string_builder.h" #include "formattedval_impl.h" U_NAMESPACE_BEGIN namespace number { @@ -29,9 +29,9 @@ namespace impl { * Possible magic number: 0x46445200 * Reads in ASCII as "FDR" (FormatteDnumberRange with room at the end) */ -class UFormattedNumberRangeData : public FormattedValueNumberStringBuilderImpl { +class UFormattedNumberRangeData : public FormattedValueStringBuilderImpl { public: - UFormattedNumberRangeData() : FormattedValueNumberStringBuilderImpl(0) {} + UFormattedNumberRangeData() : FormattedValueStringBuilderImpl(0) {} virtual ~UFormattedNumberRangeData(); DecimalQuantity quantity1; diff --git a/deps/icu-small/source/i18n/numsys.cpp b/deps/icu-small/source/i18n/numsys.cpp index 80056f925b..e3fe54bc1b 100644 --- a/deps/icu-small/source/i18n/numsys.cpp +++ b/deps/icu-small/source/i18n/numsys.cpp @@ -37,7 +37,7 @@ U_NAMESPACE_BEGIN // Useful constants -#define DEFAULT_DIGITS UNICODE_STRING_SIMPLE("0123456789"); +#define DEFAULT_DIGITS UNICODE_STRING_SIMPLE("0123456789") static const char gNumberingSystems[] = "numberingSystems"; static const char gNumberElements[] = "NumberElements"; static const char gDefault[] = "default"; diff --git a/deps/icu-small/source/i18n/olsontz.cpp b/deps/icu-small/source/i18n/olsontz.cpp index 95fc56bcd7..dd01180f8c 100644 --- a/deps/icu-small/source/i18n/olsontz.cpp +++ b/deps/icu-small/source/i18n/olsontz.cpp @@ -287,8 +287,7 @@ OlsonTimeZone& OlsonTimeZone::operator=(const OlsonTimeZone& other) { typeMapData = other.typeMapData; delete finalZone; - finalZone = (other.finalZone != 0) ? - (SimpleTimeZone*) other.finalZone->clone() : 0; + finalZone = (other.finalZone != 0) ? other.finalZone->clone() : 0; finalStartYear = other.finalStartYear; finalStartMillis = other.finalStartMillis; @@ -319,7 +318,7 @@ UBool OlsonTimeZone::operator==(const TimeZone& other) const { /** * TimeZone API. */ -TimeZone* OlsonTimeZone::clone() const { +OlsonTimeZone* OlsonTimeZone::clone() const { return new OlsonTimeZone(*this); } @@ -816,7 +815,7 @@ OlsonTimeZone::initTransitionRules(UErrorCode& status) { * For now, we do not set the valid start year when the construction time * and create a clone and set the start year when extracting rules. */ - finalZoneWithStartYear = (SimpleTimeZone*)finalZone->clone(); + finalZoneWithStartYear = finalZone->clone(); // Check to make sure finalZone was actually cloned. if (finalZoneWithStartYear == NULL) { status = U_MEMORY_ALLOCATION_ERROR; @@ -837,7 +836,7 @@ OlsonTimeZone::initTransitionRules(UErrorCode& status) { startTime = tzt.getTime(); } else { // final rule with no transitions - finalZoneWithStartYear = (SimpleTimeZone*)finalZone->clone(); + finalZoneWithStartYear = finalZone->clone(); // Check to make sure finalZone was actually cloned. if (finalZoneWithStartYear == NULL) { status = U_MEMORY_ALLOCATION_ERROR; diff --git a/deps/icu-small/source/i18n/olsontz.h b/deps/icu-small/source/i18n/olsontz.h index 6f0d36e5de..7960154698 100644 --- a/deps/icu-small/source/i18n/olsontz.h +++ b/deps/icu-small/source/i18n/olsontz.h @@ -151,7 +151,7 @@ class U_I18N_API OlsonTimeZone: public BasicTimeZone { /** * TimeZone API. */ - virtual TimeZone* clone() const; + virtual OlsonTimeZone* clone() const; /** * TimeZone API. @@ -398,7 +398,7 @@ private: TimeArrayTimeZoneRule **historicRules; int16_t historicRuleCount; SimpleTimeZone *finalZoneWithStartYear; // hack - UInitOnce transitionRulesInitOnce; + UInitOnce transitionRulesInitOnce = U_INITONCE_INITIALIZER; }; inline int16_t diff --git a/deps/icu-small/source/i18n/persncal.cpp b/deps/icu-small/source/i18n/persncal.cpp index 3d391f4e3f..4d366d41f0 100644 --- a/deps/icu-small/source/i18n/persncal.cpp +++ b/deps/icu-small/source/i18n/persncal.cpp @@ -74,7 +74,7 @@ const char *PersianCalendar::getType() const { return "persian"; } -Calendar* PersianCalendar::clone() const { +PersianCalendar* PersianCalendar::clone() const { return new PersianCalendar(*this); } diff --git a/deps/icu-small/source/i18n/persncal.h b/deps/icu-small/source/i18n/persncal.h index ec818822b3..a9d940db78 100644 --- a/deps/icu-small/source/i18n/persncal.h +++ b/deps/icu-small/source/i18n/persncal.h @@ -164,7 +164,7 @@ class PersianCalendar : public Calendar { // TODO: copy c'tor, etc // clone - virtual Calendar* clone() const; + virtual PersianCalendar* clone() const; private: /** diff --git a/deps/icu-small/source/i18n/plurfmt.cpp b/deps/icu-small/source/i18n/plurfmt.cpp index 678d91b9c8..b99437630e 100644 --- a/deps/icu-small/source/i18n/plurfmt.cpp +++ b/deps/icu-small/source/i18n/plurfmt.cpp @@ -159,7 +159,7 @@ PluralFormat::copyObjects(const PluralFormat& other) { if (other.numberFormat == NULL) { numberFormat = NumberFormat::createInstance(locale, status); } else { - numberFormat = (NumberFormat*)other.numberFormat->clone(); + numberFormat = other.numberFormat->clone(); } if (other.pluralRulesWrapper.pluralRules == NULL) { pluralRulesWrapper.pluralRules = PluralRules::forLocale(locale, status); @@ -277,7 +277,14 @@ PluralFormat::format(const Formattable& numberObject, double number, UnicodeString numberString; auto *decFmt = dynamic_cast<DecimalFormat *>(numberFormat); if(decFmt != nullptr) { - decFmt->toNumberFormatter().formatImpl(&data, status); // mutates &data + const number::LocalizedNumberFormatter* lnf = decFmt->toNumberFormatter(status); + if (U_FAILURE(status)) { + return appendTo; + } + lnf->formatImpl(&data, status); // mutates &data + if (U_FAILURE(status)) { + return appendTo; + } numberString = data.getStringRef().toUnicodeString(); } else { if (offset == 0) { @@ -346,7 +353,7 @@ PluralFormat::setNumberFormat(const NumberFormat* format, UErrorCode& status) { if (U_FAILURE(status)) { return; } - NumberFormat* nf = (NumberFormat*)format->clone(); + NumberFormat* nf = format->clone(); if (nf != NULL) { delete numberFormat; numberFormat = nf; @@ -355,7 +362,7 @@ PluralFormat::setNumberFormat(const NumberFormat* format, UErrorCode& status) { } } -Format* +PluralFormat* PluralFormat::clone() const { return new PluralFormat(*this); diff --git a/deps/icu-small/source/i18n/quant.cpp b/deps/icu-small/source/i18n/quant.cpp index 1908a50484..b0e7a3ed52 100644 --- a/deps/icu-small/source/i18n/quant.cpp +++ b/deps/icu-small/source/i18n/quant.cpp @@ -47,7 +47,7 @@ Quantifier::~Quantifier() { /** * Implement UnicodeFunctor */ -UnicodeFunctor* Quantifier::clone() const { +Quantifier* Quantifier::clone() const { return new Quantifier(*this); } diff --git a/deps/icu-small/source/i18n/quant.h b/deps/icu-small/source/i18n/quant.h index 1abb0db61a..d5aa8e5eee 100644 --- a/deps/icu-small/source/i18n/quant.h +++ b/deps/icu-small/source/i18n/quant.h @@ -45,7 +45,7 @@ class Quantifier : public UnicodeFunctor, public UnicodeMatcher { * Implement UnicodeFunctor * @return a copy of the object. */ - virtual UnicodeFunctor* clone() const; + virtual Quantifier* clone() const; /** * Implement UnicodeMatcher diff --git a/deps/icu-small/source/i18n/quantityformatter.cpp b/deps/icu-small/source/i18n/quantityformatter.cpp index 9182f9e7d3..e88b70fbd7 100644 --- a/deps/icu-small/source/i18n/quantityformatter.cpp +++ b/deps/icu-small/source/i18n/quantityformatter.cpp @@ -26,7 +26,7 @@ #include "uassert.h" #include "number_decimalquantity.h" #include "number_utypes.h" -#include "number_stringbuilder.h" +#include "formatted_string_builder.h" U_NAMESPACE_BEGIN @@ -180,7 +180,7 @@ void QuantityFormatter::formatAndSelect( double quantity, const NumberFormat& fmt, const PluralRules& rules, - number::impl::NumberStringBuilder& output, + FormattedStringBuilder& output, StandardPlural::Form& pluralForm, UErrorCode& status) { UnicodeString pluralKeyword; @@ -188,7 +188,11 @@ void QuantityFormatter::formatAndSelect( if (df != nullptr) { number::impl::UFormattedNumberData fn; fn.quantity.setToDouble(quantity); - df->toNumberFormatter().formatImpl(&fn, status); + const number::LocalizedNumberFormatter* lnf = df->toNumberFormatter(status); + if (U_FAILURE(status)) { + return; + } + lnf->formatImpl(&fn, status); if (U_FAILURE(status)) { return; } diff --git a/deps/icu-small/source/i18n/quantityformatter.h b/deps/icu-small/source/i18n/quantityformatter.h index 3e3f29de57..88c3f3844e 100644 --- a/deps/icu-small/source/i18n/quantityformatter.h +++ b/deps/icu-small/source/i18n/quantityformatter.h @@ -26,12 +26,7 @@ class PluralRules; class NumberFormat; class Formattable; class FieldPosition; - -namespace number { -namespace impl { -class NumberStringBuilder; -} -} +class FormattedStringBuilder; /** * A plural aware formatter that is good for expressing a single quantity and @@ -129,7 +124,7 @@ public: /** * Formats a quantity and selects its plural form. The output is appended - * to a NumberStringBuilder in order to retain field information. + * to a FormattedStringBuilder in order to retain field information. * * @param quantity The number to format. * @param fmt The formatter to use to format the number. @@ -144,7 +139,7 @@ public: double quantity, const NumberFormat& fmt, const PluralRules& rules, - number::impl::NumberStringBuilder& output, + FormattedStringBuilder& output, StandardPlural::Form& pluralForm, UErrorCode& status); diff --git a/deps/icu-small/source/i18n/rbnf.cpp b/deps/icu-small/source/i18n/rbnf.cpp index 74707ccd22..c25e61e6b2 100644 --- a/deps/icu-small/source/i18n/rbnf.cpp +++ b/deps/icu-small/source/i18n/rbnf.cpp @@ -355,10 +355,16 @@ private: }; #ifdef RBNF_DEBUG -#define ERROR(msg) parseError(msg); return NULL; +#define ERROR(msg) UPRV_BLOCK_MACRO_BEGIN { \ + parseError(msg); \ + return NULL; \ +} UPRV_BLOCK_MACRO_END #define EXPLANATION_ARG explanationArg #else -#define ERROR(msg) parseError(NULL); return NULL; +#define ERROR(msg) UPRV_BLOCK_MACRO_BEGIN { \ + parseError(NULL); \ + return NULL; \ +} UPRV_BLOCK_MACRO_END #define EXPLANATION_ARG #endif @@ -924,8 +930,8 @@ RuleBasedNumberFormat::~RuleBasedNumberFormat() dispose(); } -Format* -RuleBasedNumberFormat::clone(void) const +RuleBasedNumberFormat* +RuleBasedNumberFormat::clone() const { return new RuleBasedNumberFormat(*this); } @@ -1112,45 +1118,6 @@ RuleBasedNumberFormat::findRuleSet(const UnicodeString& name, UErrorCode& status UnicodeString& RuleBasedNumberFormat::format(const DecimalQuantity &number, - UnicodeString &appendTo, - FieldPositionIterator *posIter, - UErrorCode &status) const { - if (U_FAILURE(status)) { - return appendTo; - } - DecimalQuantity copy(number); - if (copy.fitsInLong()) { - format(number.toLong(), appendTo, posIter, status); - } - else { - copy.roundToMagnitude(0, number::impl::RoundingMode::UNUM_ROUND_HALFEVEN, status); - if (copy.fitsInLong()) { - format(number.toDouble(), appendTo, posIter, status); - } - else { - // We're outside of our normal range that this framework can handle. - // The DecimalFormat will provide more accurate results. - - // TODO this section should probably be optimized. The DecimalFormat is shared in ICU4J. - LocalPointer<NumberFormat> decimalFormat(NumberFormat::createInstance(locale, UNUM_DECIMAL, status), status); - if (decimalFormat.isNull()) { - return appendTo; - } - Formattable f; - LocalPointer<DecimalQuantity> decimalQuantity(new DecimalQuantity(number), status); - if (decimalQuantity.isNull()) { - return appendTo; - } - f.adoptDecimalQuantity(decimalQuantity.orphan()); // f now owns decimalQuantity. - decimalFormat->format(f, appendTo, posIter, status); - } - } - return appendTo; -} - - -UnicodeString& -RuleBasedNumberFormat::format(const DecimalQuantity &number, UnicodeString& appendTo, FieldPosition& pos, UErrorCode &status) const { diff --git a/deps/icu-small/source/i18n/rbt.cpp b/deps/icu-small/source/i18n/rbt.cpp index 8ba6a60ff4..02d0ce6ceb 100644 --- a/deps/icu-small/source/i18n/rbt.cpp +++ b/deps/icu-small/source/i18n/rbt.cpp @@ -191,8 +191,8 @@ RuleBasedTransliterator::~RuleBasedTransliterator() { } } -Transliterator* // Covariant return NOT ALLOWED (for portability) -RuleBasedTransliterator::clone(void) const { +RuleBasedTransliterator* +RuleBasedTransliterator::clone() const { return new RuleBasedTransliterator(*this); } @@ -253,7 +253,7 @@ RuleBasedTransliterator::handleTransliterate(Replaceable& text, UTransPosition& // // TODO(andy): Need a better scheme for handling this. - static UMutex transliteratorDataMutex = U_MUTEX_INITIALIZER; + static UMutex transliteratorDataMutex; UBool needToLock; { Mutex m; diff --git a/deps/icu-small/source/i18n/rbt.h b/deps/icu-small/source/i18n/rbt.h index a18452ab2e..b450dc23f4 100644 --- a/deps/icu-small/source/i18n/rbt.h +++ b/deps/icu-small/source/i18n/rbt.h @@ -144,7 +144,7 @@ public: * Implement Transliterator API. * @internal Use transliterator factory methods instead since this class will be removed in that release. */ - virtual Transliterator* clone(void) const; + virtual RuleBasedTransliterator* clone() const; protected: /** diff --git a/deps/icu-small/source/i18n/rbt_pars.cpp b/deps/icu-small/source/i18n/rbt_pars.cpp index e07cc8b63a..3eb58a2a90 100644 --- a/deps/icu-small/source/i18n/rbt_pars.cpp +++ b/deps/icu-small/source/i18n/rbt_pars.cpp @@ -1111,7 +1111,7 @@ void TransliteratorParser::parseRules(const UnicodeString& rule, int32_t p = UHASH_FIRST; const UHashElement* he = variableNames.nextElement(p); while (he != NULL) { - UnicodeString* tempus = (UnicodeString*)(((UnicodeString*)(he->value.pointer))->clone()); + UnicodeString* tempus = ((UnicodeString*)(he->value.pointer))->clone(); if (tempus == NULL) { status = U_MEMORY_ALLOCATION_ERROR; return; diff --git a/deps/icu-small/source/i18n/rbt_rule.cpp b/deps/icu-small/source/i18n/rbt_rule.cpp index db02f76035..cd7bd5d9df 100644 --- a/deps/icu-small/source/i18n/rbt_rule.cpp +++ b/deps/icu-small/source/i18n/rbt_rule.cpp @@ -180,13 +180,13 @@ TransliterationRule::TransliterationRule(TransliterationRule& other) : } if (other.anteContext != NULL) { - anteContext = (StringMatcher*) other.anteContext->clone(); + anteContext = other.anteContext->clone(); } if (other.key != NULL) { - key = (StringMatcher*) other.key->clone(); + key = other.key->clone(); } if (other.postContext != NULL) { - postContext = (StringMatcher*) other.postContext->clone(); + postContext = other.postContext->clone(); } output = other.output->clone(); } diff --git a/deps/icu-small/source/i18n/rbtz.cpp b/deps/icu-small/source/i18n/rbtz.cpp index b8dca395fc..2c3747abda 100644 --- a/deps/icu-small/source/i18n/rbtz.cpp +++ b/deps/icu-small/source/i18n/rbtz.cpp @@ -149,7 +149,7 @@ RuleBasedTimeZone::addTransitionRule(TimeZoneRule* rule, UErrorCode& status) { void RuleBasedTimeZone::completeConst(UErrorCode& status) const { - static UMutex gLock = U_MUTEX_INITIALIZER; + static UMutex gLock; if (U_FAILURE(status)) { return; } @@ -356,8 +356,8 @@ cleanup: fUpToDate = FALSE; } -TimeZone* -RuleBasedTimeZone::clone(void) const { +RuleBasedTimeZone* +RuleBasedTimeZone::clone() const { return new RuleBasedTimeZone(*this); } diff --git a/deps/icu-small/source/i18n/regexcmp.cpp b/deps/icu-small/source/i18n/regexcmp.cpp index 8d60986fd3..3a6368b07a 100644 --- a/deps/icu-small/source/i18n/regexcmp.cpp +++ b/deps/icu-small/source/i18n/regexcmp.cpp @@ -561,7 +561,7 @@ UBool RegexCompile::doParseActions(int32_t action) // sequence; don't change without making updates there too. // // Compiles to - // 1 START_LA dataLoc Saves SP, Input Pos + // 1 LA_START dataLoc Saves SP, Input Pos, Active input region. // 2. STATE_SAVE 4 on failure of lookahead, goto 4 // 3 JMP 6 continue ... // @@ -575,10 +575,14 @@ UBool RegexCompile::doParseActions(int32_t action) // 8. code for parenthesized stuff. // 9. LA_END // - // Two data slots are reserved, for saving the stack ptr and the input position. + // Four data slots are reserved, for saving state on entry to the look-around + // 0: stack pointer on entry. + // 1: input position on entry. + // 2: fActiveStart, the active bounds start on entry. + // 3: fActiveLimit, the active bounds limit on entry. { fixLiterals(); - int32_t dataLoc = allocateData(2); + int32_t dataLoc = allocateData(4); appendOp(URX_LA_START, dataLoc); appendOp(URX_STATE_SAVE, fRXPat->fCompiledPat->size()+ 2); appendOp(URX_JMP, fRXPat->fCompiledPat->size()+ 3); @@ -599,18 +603,23 @@ UBool RegexCompile::doParseActions(int32_t action) case doOpenLookAheadNeg: // Negated Lookahead. (?! stuff ) // Compiles to - // 1. START_LA dataloc + // 1. LA_START dataloc // 2. SAVE_STATE 7 // Fail within look-ahead block restores to this state, // // which continues with the match. // 3. NOP // Std. Open Paren sequence, for possible '|' // 4. code for parenthesized stuff. - // 5. END_LA // Cut back stack, remove saved state from step 2. + // 5. LA_END // Cut back stack, remove saved state from step 2. // 6. BACKTRACK // code in block succeeded, so neg. lookahead fails. // 7. END_LA // Restore match region, in case look-ahead was using // an alternate (transparent) region. + // Four data slots are reserved, for saving state on entry to the look-around + // 0: stack pointer on entry. + // 1: input position on entry. + // 2: fActiveStart, the active bounds start on entry. + // 3: fActiveLimit, the active bounds limit on entry. { fixLiterals(); - int32_t dataLoc = allocateData(2); + int32_t dataLoc = allocateData(4); appendOp(URX_LA_START, dataLoc); appendOp(URX_STATE_SAVE, 0); // dest address will be patched later. appendOp(URX_NOP, 0); @@ -644,14 +653,16 @@ UBool RegexCompile::doParseActions(int32_t action) // Allocate a block of matcher data, to contain (when running a match) // 0: Stack ptr on entry // 1: Input Index on entry - // 2: Start index of match current match attempt. - // 3: Original Input String len. + // 2: fActiveStart, the active bounds start on entry. + // 3: fActiveLimit, the active bounds limit on entry. + // 4: Start index of match current match attempt. + // The first four items must match the layout of data for LA_START / LA_END // Generate match code for any pending literals. fixLiterals(); // Allocate data space - int32_t dataLoc = allocateData(4); + int32_t dataLoc = allocateData(5); // Emit URX_LB_START appendOp(URX_LB_START, dataLoc); @@ -696,14 +707,16 @@ UBool RegexCompile::doParseActions(int32_t action) // Allocate a block of matcher data, to contain (when running a match) // 0: Stack ptr on entry // 1: Input Index on entry - // 2: Start index of match current match attempt. - // 3: Original Input String len. + // 2: fActiveStart, the active bounds start on entry. + // 3: fActiveLimit, the active bounds limit on entry. + // 4: Start index of match current match attempt. + // The first four items must match the layout of data for LA_START / LA_END // Generate match code for any pending literals. fixLiterals(); // Allocate data space - int32_t dataLoc = allocateData(4); + int32_t dataLoc = allocateData(5); // Emit URX_LB_START appendOp(URX_LB_START, dataLoc); @@ -2285,7 +2298,7 @@ void RegexCompile::handleCloseParen() { error(U_REGEX_LOOK_BEHIND_LIMIT); break; } - if (minML == INT32_MAX && maxML == 0) { + if (minML == INT32_MAX) { // This condition happens when no match is possible, such as with a // [set] expression containing no elements. // In principle, the generated code to evaluate the expression could be deleted, @@ -2328,7 +2341,7 @@ void RegexCompile::handleCloseParen() { error(U_REGEX_LOOK_BEHIND_LIMIT); break; } - if (minML == INT32_MAX && maxML == 0) { + if (minML == INT32_MAX) { // This condition happens when no match is possible, such as with a // [set] expression containing no elements. // In principle, the generated code to evaluate the expression could be deleted, @@ -3381,7 +3394,7 @@ int32_t RegexCompile::minMatchLength(int32_t start, int32_t end) { // it assumes that the look-ahead match might be zero-length. // TODO: Positive lookahead could recursively do the block, then continue // with the longer of the block or the value coming in. Ticket 6060 - int32_t depth = (opType == URX_LA_START? 2: 1);; + int32_t depth = (opType == URX_LA_START? 2: 1); for (;;) { loc++; op = (int32_t)fRXPat->fCompiledPat->elementAti(loc); @@ -3463,7 +3476,6 @@ int32_t RegexCompile::maxMatchLength(int32_t start, int32_t end) { U_ASSERT(start <= end); U_ASSERT(end < fRXPat->fCompiledPat->size()); - int32_t loc; int32_t op; int32_t opType; @@ -3672,7 +3684,7 @@ int32_t RegexCompile::maxMatchLength(int32_t start, int32_t end) { case URX_CTR_LOOP: case URX_CTR_LOOP_NG: - // These opcodes will be skipped over by code for URX_CRT_INIT. + // These opcodes will be skipped over by code for URX_CTR_INIT. // We shouldn't encounter them here. UPRV_UNREACHABLE; @@ -3700,21 +3712,15 @@ int32_t RegexCompile::maxMatchLength(int32_t start, int32_t end) { { // Look-behind. Scan forward until the matching look-around end, // without processing the look-behind block. - int32_t depth = 0; - for (;;) { - loc++; + int32_t dataLoc = URX_VAL(op); + for (loc = loc + 1; loc < end; ++loc) { op = (int32_t)fRXPat->fCompiledPat->elementAti(loc); - if (URX_TYPE(op) == URX_LA_START || URX_TYPE(op) == URX_LB_START) { - depth++; - } - if (URX_TYPE(op) == URX_LA_END || URX_TYPE(op)==URX_LBN_END) { - if (depth == 0) { - break; - } - depth--; + int32_t opType = URX_TYPE(op); + if ((opType == URX_LA_END || opType == URX_LBN_END) && (URX_VAL(op) == dataLoc)) { + break; } - U_ASSERT(loc < end); } + U_ASSERT(loc < end); } break; diff --git a/deps/icu-small/source/i18n/regeximp.h b/deps/icu-small/source/i18n/regeximp.h index da4a861bde..9155cd3a31 100644 --- a/deps/icu-small/source/i18n/regeximp.h +++ b/deps/icu-small/source/i18n/regeximp.h @@ -123,7 +123,7 @@ enum { // saved input position, FAIL rather than taking // the JMP URX_LA_START = 37, // Starting a LookAround expression. - // Save InputPos and SP in static data. + // Save InputPos, SP and active region in static data. // Operand: Static data offset for the save URX_LA_END = 38, // Ending a Lookaround expression. // Restore InputPos and Stack to saved values. diff --git a/deps/icu-small/source/i18n/region.cpp b/deps/icu-small/source/i18n/region.cpp index f182f61486..198bea8f64 100644 --- a/deps/icu-small/source/i18n/region.cpp +++ b/deps/icu-small/source/i18n/region.cpp @@ -25,7 +25,6 @@ #include "unicode/uobject.h" #include "unicode/unistr.h" #include "unicode/ures.h" -#include "unicode/decimfmt.h" #include "ucln_in.h" #include "cstring.h" #include "mutex.h" @@ -33,6 +32,7 @@ #include "umutex.h" #include "uresimp.h" #include "region_impl.h" +#include "util.h" #if !UCONFIG_NO_FORMATTING @@ -87,7 +87,6 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) { LocalUHashtablePointer newRegionIDMap(uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, &status)); LocalUHashtablePointer newNumericCodeMap(uhash_open(uhash_hashLong,uhash_compareLong,NULL,&status)); LocalUHashtablePointer newRegionAliases(uhash_open(uhash_hashUnicodeString,uhash_compareUnicodeString,NULL,&status)); - LocalPointer<DecimalFormat> df(new DecimalFormat(status), status); LocalPointer<UVector> continents(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status), status); LocalPointer<UVector> groupings(new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status), status); @@ -115,7 +114,6 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) { } // now, initialize - df->setParseIntegerOnly(TRUE); uhash_setValueDeleter(newRegionIDMap.getAlias(), deleteRegion); // regionIDMap owns objs uhash_setKeyDeleter(newRegionAliases.getAlias(), uprv_deleteUObject); // regionAliases owns the string keys @@ -192,11 +190,10 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) { r->idStr.extract(0,r->idStr.length(),r->id,sizeof(r->id),US_INV); r->fType = URGN_TERRITORY; // Only temporary - figure out the real type later once the aliases are known. - Formattable result; - UErrorCode ps = U_ZERO_ERROR; - df->parse(r->idStr,result,ps); - if ( U_SUCCESS(ps) ) { - r->code = result.getLong(); // Convert string to number + int32_t pos = 0; + int32_t result = ICU_Utility::parseAsciiInteger(r->idStr, pos); + if (pos > 0) { + r->code = result; // Convert string to number uhash_iput(newNumericCodeMap.getAlias(),r->code,(void *)(r.getAlias()),&status); r->fType = URGN_SUBCONTINENT; } else { @@ -230,11 +227,10 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) { aliasFromRegion->idStr.setTo(*aliasFromStr); aliasFromRegion->idStr.extract(0,aliasFromRegion->idStr.length(),aliasFromRegion->id,sizeof(aliasFromRegion->id),US_INV); uhash_put(newRegionIDMap.getAlias(),(void *)&(aliasFromRegion->idStr),(void *)aliasFromRegion,&status); - Formattable result; - UErrorCode ps = U_ZERO_ERROR; - df->parse(aliasFromRegion->idStr,result,ps); - if ( U_SUCCESS(ps) ) { - aliasFromRegion->code = result.getLong(); // Convert string to number + int32_t pos = 0; + int32_t result = ICU_Utility::parseAsciiInteger(aliasFromRegion->idStr, pos); + if ( pos > 0 ) { + aliasFromRegion->code = result; // Convert string to number uhash_iput(newNumericCodeMap.getAlias(),aliasFromRegion->code,(void *)aliasFromRegion,&status); } else { aliasFromRegion->code = -1; @@ -279,11 +275,10 @@ void U_CALLCONV Region::loadRegionData(UErrorCode &status) { Region *r = (Region *)uhash_get(newRegionIDMap.getAlias(),(void *)&codeMappingID); if ( r ) { - Formattable result; - UErrorCode ps = U_ZERO_ERROR; - df->parse(codeMappingNumber,result,ps); - if ( U_SUCCESS(ps) ) { - r->code = result.getLong(); // Convert string to number + int32_t pos = 0; + int32_t result = ICU_Utility::parseAsciiInteger(codeMappingNumber, pos); + if ( pos > 0 ) { + r->code = result; // Convert string to number uhash_iput(newNumericCodeMap.getAlias(),r->code,(void *)r,&status); } LocalPointer<UnicodeString> code3(new UnicodeString(codeMapping3Letter), status); @@ -516,15 +511,8 @@ Region::getInstance (int32_t code, UErrorCode &status) { Region *r = (Region *)uhash_iget(numericCodeMap,code); if ( !r ) { // Just in case there's an alias that's numeric, try to find it. - UnicodeString pat = UNICODE_STRING_SIMPLE("0"); - LocalPointer<DecimalFormat> df(new DecimalFormat(pat,status), status); - if( U_FAILURE(status) ) { - return NULL; - } UnicodeString id; - id.remove(); - FieldPosition posIter; - df->format(code,id, posIter, status); + ICU_Utility::appendNumber(id, code, 10, 1); r = (Region *)uhash_get(regionAliases,&id); } diff --git a/deps/icu-small/source/i18n/reldatefmt.cpp b/deps/icu-small/source/i18n/reldatefmt.cpp index cda2564b9a..f2568a858d 100644 --- a/deps/icu-small/source/i18n/reldatefmt.cpp +++ b/deps/icu-small/source/i18n/reldatefmt.cpp @@ -43,7 +43,7 @@ #include "standardplural.h" #include "unifiedcache.h" #include "util.h" -#include "number_stringbuilder.h" +#include "formatted_string_builder.h" #include "number_utypes.h" #include "number_modifiers.h" #include "formattedval_impl.h" @@ -315,6 +315,10 @@ struct RelDateTimeFmtDataSink : public ResourceSink { return UDAT_ABSOLUTE_FRIDAY; case SATURDAY: return UDAT_ABSOLUTE_SATURDAY; + case HOUR: + return UDAT_ABSOLUTE_HOUR; + case MINUTE: + return UDAT_ABSOLUTE_MINUTE; default: return -1; } @@ -725,14 +729,14 @@ const RelativeDateTimeCacheData *LocaleCacheKey<RelativeDateTimeCacheData>::crea static constexpr number::impl::Field kRDTNumericField - = number::impl::NumFieldUtils::compress<UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_NUMERIC_FIELD>(); + = StringBuilderFieldUtils::compress<UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_NUMERIC_FIELD>(); static constexpr number::impl::Field kRDTLiteralField - = number::impl::NumFieldUtils::compress<UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD>(); + = StringBuilderFieldUtils::compress<UFIELD_CATEGORY_RELATIVE_DATETIME, UDAT_REL_LITERAL_FIELD>(); -class FormattedRelativeDateTimeData : public FormattedValueNumberStringBuilderImpl { +class FormattedRelativeDateTimeData : public FormattedValueStringBuilderImpl { public: - FormattedRelativeDateTimeData() : FormattedValueNumberStringBuilderImpl(kRDTNumericField) {} + FormattedRelativeDateTimeData() : FormattedValueStringBuilderImpl(kRDTNumericField) {} virtual ~FormattedRelativeDateTimeData(); }; @@ -1157,6 +1161,8 @@ void RelativeDateTimeFormatter::formatRelativeImpl( case UDAT_REL_UNIT_THURSDAY: absunit = UDAT_ABSOLUTE_THURSDAY; break; case UDAT_REL_UNIT_FRIDAY: absunit = UDAT_ABSOLUTE_FRIDAY; break; case UDAT_REL_UNIT_SATURDAY: absunit = UDAT_ABSOLUTE_SATURDAY; break; + case UDAT_REL_UNIT_HOUR: absunit = UDAT_ABSOLUTE_HOUR; break; + case UDAT_REL_UNIT_MINUTE: absunit = UDAT_ABSOLUTE_MINUTE; break; default: break; } if (direction != UDAT_DIRECTION_COUNT && absunit != UDAT_ABSOLUTE_UNIT_COUNT) { @@ -1184,7 +1190,7 @@ UnicodeString& RelativeDateTimeFormatter::adjustForContext(UnicodeString &str) c // Must guarantee that one thread at a time accesses the shared break // iterator. - static icu::UMutex gBrkIterMutex = U_MUTEX_INITIALIZER; + static UMutex gBrkIterMutex; Mutex lock(&gBrkIterMutex); str.toTitle( fOptBreakIterator->get(), diff --git a/deps/icu-small/source/i18n/reldtfmt.cpp b/deps/icu-small/source/i18n/reldtfmt.cpp index 753672d905..c74c30c20c 100644 --- a/deps/icu-small/source/i18n/reldtfmt.cpp +++ b/deps/icu-small/source/i18n/reldtfmt.cpp @@ -51,7 +51,7 @@ RelativeDateFormat::RelativeDateFormat(const RelativeDateFormat& other) : fCapitalizationBrkIter(NULL) { if(other.fDateTimeFormatter != NULL) { - fDateTimeFormatter = (SimpleDateFormat*)other.fDateTimeFormatter->clone(); + fDateTimeFormatter = other.fDateTimeFormatter->clone(); } if(other.fCombinedFormat != NULL) { fCombinedFormat = new SimpleFormatter(*other.fCombinedFormat); @@ -131,7 +131,7 @@ RelativeDateFormat::~RelativeDateFormat() { } -Format* RelativeDateFormat::clone(void) const { +RelativeDateFormat* RelativeDateFormat::clone() const { return new RelativeDateFormat(*this); } diff --git a/deps/icu-small/source/i18n/reldtfmt.h b/deps/icu-small/source/i18n/reldtfmt.h index 0403da11ef..b36171ce1c 100644 --- a/deps/icu-small/source/i18n/reldtfmt.h +++ b/deps/icu-small/source/i18n/reldtfmt.h @@ -71,7 +71,7 @@ public: * @return A copy of the object. * @internal ICU 3.8 */ - virtual Format* clone(void) const; + virtual RelativeDateFormat* clone() const; /** * Return true if the given Format objects are semantically equal. Objects diff --git a/deps/icu-small/source/i18n/rematch.cpp b/deps/icu-small/source/i18n/rematch.cpp index 3b8d2333d8..d9af2b3dda 100644 --- a/deps/icu-small/source/i18n/rematch.cpp +++ b/deps/icu-small/source/i18n/rematch.cpp @@ -2069,7 +2069,7 @@ int32_t RegexMatcher::split(UText *input, // if (U_FAILURE(status)) { return 0; - }; + } if (destCapacity < 1) { status = U_ILLEGAL_ARGUMENT_ERROR; @@ -3805,11 +3805,13 @@ GC_Done: case URX_LA_START: { - // Entering a lookahead block. + // Entering a look around block. // Save Stack Ptr, Input Pos. - U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize); + U_ASSERT(opValue>=0 && opValue+3<fPattern->fDataSize); fData[opValue] = fStack->size(); fData[opValue+1] = fp->fInputIdx; + fData[opValue+2] = fActiveStart; + fData[opValue+3] = fActiveLimit; fActiveStart = fLookStart; // Set the match region change for fActiveLimit = fLookLimit; // transparent bounds. } @@ -3819,7 +3821,7 @@ GC_Done: { // Leaving a look-ahead block. // restore Stack Ptr, Input Pos to positions they had on entry to block. - U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize); + U_ASSERT(opValue>=0 && opValue+3<fPattern->fDataSize); int32_t stackSize = fStack->size(); int32_t newStackSize =(int32_t)fData[opValue]; U_ASSERT(stackSize >= newStackSize); @@ -3839,8 +3841,10 @@ GC_Done: // Restore the active region bounds in the input string; they may have // been changed because of transparent bounds on a Region. - fActiveStart = fRegionStart; - fActiveLimit = fRegionLimit; + fActiveStart = fData[opValue+2]; + fActiveLimit = fData[opValue+3]; + U_ASSERT(fActiveStart >= 0); + U_ASSERT(fActiveLimit <= fInputLength); } break; @@ -3916,17 +3920,19 @@ GC_Done: case URX_LB_START: { // Entering a look-behind block. - // Save Stack Ptr, Input Pos. + // Save Stack Ptr, Input Pos and active input region. // TODO: implement transparent bounds. Ticket #6067 - U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize); + U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize); fData[opValue] = fStack->size(); fData[opValue+1] = fp->fInputIdx; - // Init the variable containing the start index for attempted matches. - fData[opValue+2] = -1; // Save input string length, then reset to pin any matches to end at // the current position. + fData[opValue+2] = fActiveStart; fData[opValue+3] = fActiveLimit; + fActiveStart = fRegionStart; fActiveLimit = fp->fInputIdx; + // Init the variable containing the start index for attempted matches. + fData[opValue+4] = -1; } break; @@ -3949,8 +3955,8 @@ GC_Done: U_ASSERT(minML >= 0); // Fetch (from data) the last input index where a match was attempted. - U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize); - int64_t &lbStartIdx = fData[opValue+2]; + U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize); + int64_t &lbStartIdx = fData[opValue+4]; if (lbStartIdx < 0) { // First time through loop. lbStartIdx = fp->fInputIdx - minML; @@ -3976,10 +3982,10 @@ GC_Done: // getting a match. Backtrack out, and out of the // Look Behind altogether. fp = (REStackFrame *)fStack->popFrame(fFrameSize); - int64_t restoreInputLen = fData[opValue+3]; - U_ASSERT(restoreInputLen >= fActiveLimit); - U_ASSERT(restoreInputLen <= fInputLength); - fActiveLimit = restoreInputLen; + fActiveStart = fData[opValue+2]; + fActiveLimit = fData[opValue+3]; + U_ASSERT(fActiveStart >= 0); + U_ASSERT(fActiveLimit <= fInputLength); break; } @@ -3993,7 +3999,7 @@ GC_Done: case URX_LB_END: // End of a look-behind block, after a successful match. { - U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize); + U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize); if (fp->fInputIdx != fActiveLimit) { // The look-behind expression matched, but the match did not // extend all the way to the point that we are looking behind from. @@ -4004,13 +4010,13 @@ GC_Done: break; } - // Look-behind match is good. Restore the orignal input string length, + // Look-behind match is good. Restore the orignal input string region, // which had been truncated to pin the end of the lookbehind match to the // position being looked-behind. - int64_t originalInputLen = fData[opValue+3]; - U_ASSERT(originalInputLen >= fActiveLimit); - U_ASSERT(originalInputLen <= fInputLength); - fActiveLimit = originalInputLen; + fActiveStart = fData[opValue+2]; + fActiveLimit = fData[opValue+3]; + U_ASSERT(fActiveStart >= 0); + U_ASSERT(fActiveLimit <= fInputLength); } break; @@ -4035,8 +4041,8 @@ GC_Done: U_ASSERT(continueLoc > fp->fPatIdx); // Fetch (from data) the last input index where a match was attempted. - U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize); - int64_t &lbStartIdx = fData[opValue+2]; + U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize); + int64_t &lbStartIdx = fData[opValue+4]; if (lbStartIdx < 0) { // First time through loop. lbStartIdx = fp->fInputIdx - minML; @@ -4061,10 +4067,10 @@ GC_Done: // We have tried all potential match starting points without // getting a match, which means that the negative lookbehind as // a whole has succeeded. Jump forward to the continue location - int64_t restoreInputLen = fData[opValue+3]; - U_ASSERT(restoreInputLen >= fActiveLimit); - U_ASSERT(restoreInputLen <= fInputLength); - fActiveLimit = restoreInputLen; + fActiveStart = fData[opValue+2]; + fActiveLimit = fData[opValue+3]; + U_ASSERT(fActiveStart >= 0); + U_ASSERT(fActiveLimit <= fInputLength); fp->fPatIdx = continueLoc; break; } @@ -4079,7 +4085,7 @@ GC_Done: case URX_LBN_END: // End of a negative look-behind block, after a successful match. { - U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize); + U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize); if (fp->fInputIdx != fActiveLimit) { // The look-behind expression matched, but the match did not // extend all the way to the point that we are looking behind from. @@ -4096,10 +4102,10 @@ GC_Done: // Restore the orignal input string length, which had been truncated // inorder to pin the end of the lookbehind match // to the position being looked-behind. - int64_t originalInputLen = fData[opValue+3]; - U_ASSERT(originalInputLen >= fActiveLimit); - U_ASSERT(originalInputLen <= fInputLength); - fActiveLimit = originalInputLen; + fActiveStart = fData[opValue+2]; + fActiveLimit = fData[opValue+3]; + U_ASSERT(fActiveStart >= 0); + U_ASSERT(fActiveLimit <= fInputLength); // Restore original stack position, discarding any state saved // by the successful pattern match. @@ -5336,11 +5342,13 @@ GC_Done: case URX_LA_START: { - // Entering a lookahead block. + // Entering a look around block. // Save Stack Ptr, Input Pos. - U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize); + U_ASSERT(opValue>=0 && opValue+3<fPattern->fDataSize); fData[opValue] = fStack->size(); fData[opValue+1] = fp->fInputIdx; + fData[opValue+2] = fActiveStart; + fData[opValue+3] = fActiveLimit; fActiveStart = fLookStart; // Set the match region change for fActiveLimit = fLookLimit; // transparent bounds. } @@ -5348,9 +5356,9 @@ GC_Done: case URX_LA_END: { - // Leaving a look-ahead block. + // Leaving a look around block. // restore Stack Ptr, Input Pos to positions they had on entry to block. - U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize); + U_ASSERT(opValue>=0 && opValue+3<fPattern->fDataSize); int32_t stackSize = fStack->size(); int32_t newStackSize = (int32_t)fData[opValue]; U_ASSERT(stackSize >= newStackSize); @@ -5370,8 +5378,10 @@ GC_Done: // Restore the active region bounds in the input string; they may have // been changed because of transparent bounds on a Region. - fActiveStart = fRegionStart; - fActiveLimit = fRegionLimit; + fActiveStart = fData[opValue+2]; + fActiveLimit = fData[opValue+3]; + U_ASSERT(fActiveStart >= 0); + U_ASSERT(fActiveLimit <= fInputLength); } break; @@ -5434,17 +5444,19 @@ GC_Done: case URX_LB_START: { // Entering a look-behind block. - // Save Stack Ptr, Input Pos. + // Save Stack Ptr, Input Pos and active input region. // TODO: implement transparent bounds. Ticket #6067 - U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize); + U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize); fData[opValue] = fStack->size(); fData[opValue+1] = fp->fInputIdx; - // Init the variable containing the start index for attempted matches. - fData[opValue+2] = -1; // Save input string length, then reset to pin any matches to end at // the current position. + fData[opValue+2] = fActiveStart; fData[opValue+3] = fActiveLimit; + fActiveStart = fRegionStart; fActiveLimit = fp->fInputIdx; + // Init the variable containing the start index for attempted matches. + fData[opValue+4] = -1; } break; @@ -5462,8 +5474,8 @@ GC_Done: U_ASSERT(minML >= 0); // Fetch (from data) the last input index where a match was attempted. - U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize); - int64_t &lbStartIdx = fData[opValue+2]; + U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize); + int64_t &lbStartIdx = fData[opValue+4]; if (lbStartIdx < 0) { // First time through loop. lbStartIdx = fp->fInputIdx - minML; @@ -5485,10 +5497,10 @@ GC_Done: // getting a match. Backtrack out, and out of the // Look Behind altogether. fp = (REStackFrame *)fStack->popFrame(fFrameSize); - int64_t restoreInputLen = fData[opValue+3]; - U_ASSERT(restoreInputLen >= fActiveLimit); - U_ASSERT(restoreInputLen <= fInputLength); - fActiveLimit = restoreInputLen; + fActiveStart = fData[opValue+2]; + fActiveLimit = fData[opValue+3]; + U_ASSERT(fActiveStart >= 0); + U_ASSERT(fActiveLimit <= fInputLength); break; } @@ -5502,7 +5514,7 @@ GC_Done: case URX_LB_END: // End of a look-behind block, after a successful match. { - U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize); + U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize); if (fp->fInputIdx != fActiveLimit) { // The look-behind expression matched, but the match did not // extend all the way to the point that we are looking behind from. @@ -5513,13 +5525,13 @@ GC_Done: break; } - // Look-behind match is good. Restore the orignal input string length, + // Look-behind match is good. Restore the orignal input string region, // which had been truncated to pin the end of the lookbehind match to the // position being looked-behind. - int64_t originalInputLen = fData[opValue+3]; - U_ASSERT(originalInputLen >= fActiveLimit); - U_ASSERT(originalInputLen <= fInputLength); - fActiveLimit = originalInputLen; + fActiveStart = fData[opValue+2]; + fActiveLimit = fData[opValue+3]; + U_ASSERT(fActiveStart >= 0); + U_ASSERT(fActiveLimit <= fInputLength); } break; @@ -5539,8 +5551,8 @@ GC_Done: U_ASSERT(continueLoc > fp->fPatIdx); // Fetch (from data) the last input index where a match was attempted. - U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize); - int64_t &lbStartIdx = fData[opValue+2]; + U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize); + int64_t &lbStartIdx = fData[opValue+4]; if (lbStartIdx < 0) { // First time through loop. lbStartIdx = fp->fInputIdx - minML; @@ -5561,10 +5573,10 @@ GC_Done: // We have tried all potential match starting points without // getting a match, which means that the negative lookbehind as // a whole has succeeded. Jump forward to the continue location - int64_t restoreInputLen = fData[opValue+3]; - U_ASSERT(restoreInputLen >= fActiveLimit); - U_ASSERT(restoreInputLen <= fInputLength); - fActiveLimit = restoreInputLen; + fActiveStart = fData[opValue+2]; + fActiveLimit = fData[opValue+3]; + U_ASSERT(fActiveStart >= 0); + U_ASSERT(fActiveLimit <= fInputLength); fp->fPatIdx = continueLoc; break; } @@ -5579,7 +5591,7 @@ GC_Done: case URX_LBN_END: // End of a negative look-behind block, after a successful match. { - U_ASSERT(opValue>=0 && opValue+1<fPattern->fDataSize); + U_ASSERT(opValue>=0 && opValue+4<fPattern->fDataSize); if (fp->fInputIdx != fActiveLimit) { // The look-behind expression matched, but the match did not // extend all the way to the point that we are looking behind from. @@ -5596,10 +5608,10 @@ GC_Done: // Restore the orignal input string length, which had been truncated // inorder to pin the end of the lookbehind match // to the position being looked-behind. - int64_t originalInputLen = fData[opValue+3]; - U_ASSERT(originalInputLen >= fActiveLimit); - U_ASSERT(originalInputLen <= fInputLength); - fActiveLimit = originalInputLen; + fActiveStart = fData[opValue+2]; + fActiveLimit = fData[opValue+3]; + U_ASSERT(fActiveStart >= 0); + U_ASSERT(fActiveLimit <= fInputLength); // Restore original stack position, discarding any state saved // by the successful pattern match. diff --git a/deps/icu-small/source/i18n/remtrans.cpp b/deps/icu-small/source/i18n/remtrans.cpp index 70a6ed3935..03b878575c 100644 --- a/deps/icu-small/source/i18n/remtrans.cpp +++ b/deps/icu-small/source/i18n/remtrans.cpp @@ -48,10 +48,10 @@ RemoveTransliterator::RemoveTransliterator() : Transliterator(UnicodeString(TRUE RemoveTransliterator::~RemoveTransliterator() {} -Transliterator* RemoveTransliterator::clone(void) const { - Transliterator* result = new RemoveTransliterator(); +RemoveTransliterator* RemoveTransliterator::clone() const { + RemoveTransliterator* result = new RemoveTransliterator(); if (result != NULL && getFilter() != 0) { - result->adoptFilter((UnicodeFilter*)(getFilter()->clone())); + result->adoptFilter(getFilter()->clone()); } return result; } diff --git a/deps/icu-small/source/i18n/remtrans.h b/deps/icu-small/source/i18n/remtrans.h index ed038d5f2f..13de01594a 100644 --- a/deps/icu-small/source/i18n/remtrans.h +++ b/deps/icu-small/source/i18n/remtrans.h @@ -47,7 +47,7 @@ public: * Transliterator API. * @return A copy of the object. */ - virtual Transliterator* clone(void) const; + virtual RemoveTransliterator* clone() const; /** * Implements {@link Transliterator#handleTransliterate}. diff --git a/deps/icu-small/source/i18n/repattrn.cpp b/deps/icu-small/source/i18n/repattrn.cpp index b03873066c..6976056dc1 100644 --- a/deps/icu-small/source/i18n/repattrn.cpp +++ b/deps/icu-small/source/i18n/repattrn.cpp @@ -646,7 +646,7 @@ int32_t RegexPattern::split(const UnicodeString &input, { if (U_FAILURE(status)) { return 0; - }; + } RegexMatcher m(this); int32_t r = 0; @@ -667,7 +667,7 @@ int32_t RegexPattern::split(UText *input, { if (U_FAILURE(status)) { return 0; - }; + } RegexMatcher m(this); int32_t r = 0; diff --git a/deps/icu-small/source/i18n/rulebasedcollator.cpp b/deps/icu-small/source/i18n/rulebasedcollator.cpp index 92fa538597..60acf17815 100644 --- a/deps/icu-small/source/i18n/rulebasedcollator.cpp +++ b/deps/icu-small/source/i18n/rulebasedcollator.cpp @@ -220,7 +220,7 @@ RuleBasedCollator::adoptTailoring(CollationTailoring *t, UErrorCode &errorCode) actualLocaleIsSameAsValid = FALSE; } -Collator * +RuleBasedCollator * RuleBasedCollator::clone() const { return new RuleBasedCollator(*this); } diff --git a/deps/icu-small/source/i18n/scientificnumberformatter.cpp b/deps/icu-small/source/i18n/scientificnumberformatter.cpp index 03d98dd6e1..6c2cb3aeed 100644 --- a/deps/icu-small/source/i18n/scientificnumberformatter.cpp +++ b/deps/icu-small/source/i18n/scientificnumberformatter.cpp @@ -121,7 +121,7 @@ ScientificNumberFormatter *ScientificNumberFormatter::createInstance( return result; } -ScientificNumberFormatter::Style *ScientificNumberFormatter::SuperscriptStyle::clone() const { +ScientificNumberFormatter::SuperscriptStyle *ScientificNumberFormatter::SuperscriptStyle::clone() const { return new ScientificNumberFormatter::SuperscriptStyle(*this); } @@ -195,7 +195,7 @@ UnicodeString &ScientificNumberFormatter::SuperscriptStyle::format( return appendTo; } -ScientificNumberFormatter::Style *ScientificNumberFormatter::MarkupStyle::clone() const { +ScientificNumberFormatter::MarkupStyle *ScientificNumberFormatter::MarkupStyle::clone() const { return new ScientificNumberFormatter::MarkupStyle(*this); } diff --git a/deps/icu-small/source/i18n/selfmt.cpp b/deps/icu-small/source/i18n/selfmt.cpp index 29aee36457..47e53d75de 100644 --- a/deps/icu-small/source/i18n/selfmt.cpp +++ b/deps/icu-small/source/i18n/selfmt.cpp @@ -151,7 +151,7 @@ int32_t SelectFormat::findSubMessage(const MessagePattern& pattern, int32_t part return msgStart; } -Format* SelectFormat::clone() const +SelectFormat* SelectFormat::clone() const { return new SelectFormat(*this); } diff --git a/deps/icu-small/source/i18n/simpletz.cpp b/deps/icu-small/source/i18n/simpletz.cpp index 1af5292a82..12c220595c 100644 --- a/deps/icu-small/source/i18n/simpletz.cpp +++ b/deps/icu-small/source/i18n/simpletz.cpp @@ -33,6 +33,7 @@ #include "unicode/gregocal.h" #include "unicode/smpdtfmt.h" +#include "cmemory.h" #include "gregoimp.h" #include "umutex.h" @@ -242,7 +243,7 @@ SimpleTimeZone::operator==(const TimeZone& that) const // ------------------------------------- // Called by TimeZone::createDefault() inside a Mutex - be careful. -TimeZone* +SimpleTimeZone* SimpleTimeZone::clone() const { return new SimpleTimeZone(*this); @@ -1083,7 +1084,7 @@ SimpleTimeZone::checkTransitionRules(UErrorCode& status) const { if (U_FAILURE(status)) { return; } - static UMutex gLock = U_MUTEX_INITIALIZER; + static UMutex gLock; umtx_lock(&gLock); if (!transitionRulesInitialized) { SimpleTimeZone *ncThis = const_cast<SimpleTimeZone*>(this); diff --git a/deps/icu-small/source/i18n/smpdtfmt.cpp b/deps/icu-small/source/i18n/smpdtfmt.cpp index e67c453828..5fcbb5875b 100644 --- a/deps/icu-small/source/i18n/smpdtfmt.cpp +++ b/deps/icu-small/source/i18n/smpdtfmt.cpp @@ -230,10 +230,7 @@ static const int32_t gFieldRangeBias[] = { static const int32_t HEBREW_CAL_CUR_MILLENIUM_START_YEAR = 5000; static const int32_t HEBREW_CAL_CUR_MILLENIUM_END_YEAR = 6000; -static UMutex *LOCK() { - static UMutex m = U_MUTEX_INITIALIZER; - return &m; -} +static UMutex LOCK; UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleDateFormat) @@ -623,7 +620,7 @@ SimpleDateFormat& SimpleDateFormat::operator=(const SimpleDateFormat& other) //---------------------------------------------------------------------- -Format* +SimpleDateFormat* SimpleDateFormat::clone() const { return new SimpleDateFormat(*this); @@ -1223,10 +1220,14 @@ _appendSymbolWithMonthPattern(UnicodeString& dst, int32_t value, const UnicodeSt //---------------------------------------------------------------------- static number::LocalizedNumberFormatter* -createFastFormatter(const DecimalFormat* df, int32_t minInt, int32_t maxInt) { - return new number::LocalizedNumberFormatter( - df->toNumberFormatter() - .integerWidth(number::IntegerWidth::zeroFillTo(minInt).truncateAt(maxInt))); +createFastFormatter(const DecimalFormat* df, int32_t minInt, int32_t maxInt, UErrorCode& status) { + const number::LocalizedNumberFormatter* lnfBase = df->toNumberFormatter(status); + if (U_FAILURE(status)) { + return nullptr; + } + return lnfBase->integerWidth( + number::IntegerWidth::zeroFillTo(minInt).truncateAt(maxInt) + ).clone().orphan(); } void SimpleDateFormat::initFastNumberFormatters(UErrorCode& status) { @@ -1237,11 +1238,11 @@ void SimpleDateFormat::initFastNumberFormatters(UErrorCode& status) { if (df == nullptr) { return; } - fFastNumberFormatters[SMPDTFMT_NF_1x10] = createFastFormatter(df, 1, 10); - fFastNumberFormatters[SMPDTFMT_NF_2x10] = createFastFormatter(df, 2, 10); - fFastNumberFormatters[SMPDTFMT_NF_3x10] = createFastFormatter(df, 3, 10); - fFastNumberFormatters[SMPDTFMT_NF_4x10] = createFastFormatter(df, 4, 10); - fFastNumberFormatters[SMPDTFMT_NF_2x2] = createFastFormatter(df, 2, 2); + fFastNumberFormatters[SMPDTFMT_NF_1x10] = createFastFormatter(df, 1, 10, status); + fFastNumberFormatters[SMPDTFMT_NF_2x10] = createFastFormatter(df, 2, 10, status); + fFastNumberFormatters[SMPDTFMT_NF_3x10] = createFastFormatter(df, 3, 10, status); + fFastNumberFormatters[SMPDTFMT_NF_4x10] = createFastFormatter(df, 4, 10, status); + fFastNumberFormatters[SMPDTFMT_NF_2x2] = createFastFormatter(df, 2, 2, status); } void SimpleDateFormat::freeFastNumberFormatters() { @@ -1266,14 +1267,14 @@ SimpleDateFormat::initNumberFormatters(const Locale &locale,UErrorCode &status) if ( fDateOverride.isBogus() && fTimeOverride.isBogus() ) { return; } - umtx_lock(LOCK()); + umtx_lock(&LOCK); if (fSharedNumberFormatters == NULL) { fSharedNumberFormatters = allocSharedNumberFormatters(); if (fSharedNumberFormatters == NULL) { status = U_MEMORY_ALLOCATION_ERROR; } } - umtx_unlock(LOCK()); + umtx_unlock(&LOCK); if (U_FAILURE(status)) { return; @@ -1980,9 +1981,11 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo, break; } if (titlecase) { + BreakIterator* const mutableCapitalizationBrkIter = fCapitalizationBrkIter->clone(); UnicodeString firstField(appendTo, beginOffset); - firstField.toTitle(fCapitalizationBrkIter, fLocale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT); + firstField.toTitle(mutableCapitalizationBrkIter, fLocale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT); appendTo.replaceBetween(beginOffset, appendTo.length(), firstField); + delete mutableCapitalizationBrkIter; } } #endif @@ -2107,7 +2110,7 @@ SimpleDateFormat::zeroPaddingNumber( // Fall back to slow path (clone and mutate the NumberFormat) if (currentNumberFormat != nullptr) { FieldPosition pos(FieldPosition::DONT_CARE); - LocalPointer<NumberFormat> nf(dynamic_cast<NumberFormat*>(currentNumberFormat->clone())); + LocalPointer<NumberFormat> nf(currentNumberFormat->clone()); nf->setMinimumIntegerDigits(minDigits); nf->setMaximumIntegerDigits(maxDigits); nf->format(value, appendTo, pos); // 3rd arg is there to speed up processing @@ -3770,7 +3773,7 @@ void SimpleDateFormat::parseInt(const UnicodeString& text, auto* fmtAsDF = dynamic_cast<const DecimalFormat*>(fmt); LocalPointer<DecimalFormat> df; if (!allowNegative && fmtAsDF != nullptr) { - df.adoptInstead(dynamic_cast<DecimalFormat*>(fmtAsDF->clone())); + df.adoptInstead(fmtAsDF->clone()); if (df.isNull()) { // Memory allocation error return; @@ -3901,11 +3904,11 @@ SimpleDateFormat::applyPattern(const UnicodeString& pattern) } else if (fDateOverride.isBogus() && fHasHanYearChar) { // No current override (=> no Gannen numbering) but new pattern needs it; // use procedures from initNUmberFormatters / adoptNumberFormat - umtx_lock(LOCK()); + umtx_lock(&LOCK); if (fSharedNumberFormatters == NULL) { fSharedNumberFormatters = allocSharedNumberFormatters(); } - umtx_unlock(LOCK()); + umtx_unlock(&LOCK); if (fSharedNumberFormatters != NULL) { Locale ovrLoc(fLocale.getLanguage(),fLocale.getCountry(),fLocale.getVariant(),"numbers=jpanyear"); UErrorCode status = U_ZERO_ERROR; @@ -3998,6 +4001,7 @@ void SimpleDateFormat::adoptCalendar(Calendar* calendarToAdopt) DateFormatSymbols *newSymbols = DateFormatSymbols::createForLocale(calLocale, status); if (U_FAILURE(status)) { + delete calendarToAdopt; return; } DateFormat::adoptCalendar(calendarToAdopt); @@ -4237,7 +4241,7 @@ SimpleDateFormat::skipUWhiteSpace(const UnicodeString& text, int32_t pos) const TimeZoneFormat * SimpleDateFormat::tzFormat(UErrorCode &status) const { if (fTimeZoneFormat == NULL) { - umtx_lock(LOCK()); + umtx_lock(&LOCK); { if (fTimeZoneFormat == NULL) { TimeZoneFormat *tzfmt = TimeZoneFormat::createInstance(fLocale, status); @@ -4248,7 +4252,7 @@ SimpleDateFormat::tzFormat(UErrorCode &status) const { const_cast<SimpleDateFormat *>(this)->fTimeZoneFormat = tzfmt; } } - umtx_unlock(LOCK()); + umtx_unlock(&LOCK); } return fTimeZoneFormat; } diff --git a/deps/icu-small/source/i18n/numparse_stringsegment.cpp b/deps/icu-small/source/i18n/string_segment.cpp index 3db4fe618a..5d19ac57f5 100644 --- a/deps/icu-small/source/i18n/numparse_stringsegment.cpp +++ b/deps/icu-small/source/i18n/string_segment.cpp @@ -10,14 +10,12 @@ #define UNISTR_FROM_STRING_EXPLICIT #include "numparse_types.h" -#include "numparse_stringsegment.h" +#include "string_segment.h" #include "putilimp.h" #include "unicode/utf16.h" #include "unicode/uniset.h" -using namespace icu; -using namespace icu::numparse; -using namespace icu::numparse::impl; +U_NAMESPACE_BEGIN StringSegment::StringSegment(const UnicodeString& str, bool ignoreCase) @@ -143,4 +141,5 @@ bool StringSegment::operator==(const UnicodeString& other) const { } +U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/string_segment.h b/deps/icu-small/source/i18n/string_segment.h new file mode 100644 index 0000000000..b581f7e575 --- /dev/null +++ b/deps/icu-small/source/i18n/string_segment.h @@ -0,0 +1,134 @@ +// © 2018 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING +#ifndef __NUMPARSE_STRINGSEGMENT_H__ +#define __NUMPARSE_STRINGSEGMENT_H__ + +#include "unicode/unistr.h" +#include "unicode/uniset.h" + +U_NAMESPACE_BEGIN + + +/** + * A mutable UnicodeString wrapper with a variable offset and length and + * support for case folding. The charAt, length, and subSequence methods all + * operate relative to the fixed offset into the UnicodeString. + * + * Intended to be useful for parsing. + * + * CAUTION: Since this class is mutable, it must not be used anywhere that an + * immutable object is required, like in a cache or as the key of a hash map. + * + * @author sffc (Shane Carr) + */ +// Exported as U_I18N_API for tests +class U_I18N_API StringSegment : public UMemory { + public: + StringSegment(const UnicodeString& str, bool ignoreCase); + + int32_t getOffset() const; + + void setOffset(int32_t start); + + /** + * Equivalent to <code>setOffset(getOffset()+delta)</code>. + * + * <p> + * This method is usually called by a Matcher to register that a char was consumed. If the char is + * strong (it usually is, except for things like whitespace), follow this with a call to + * {@link ParsedNumber#setCharsConsumed}. For more information on strong chars, see that method. + */ + void adjustOffset(int32_t delta); + + /** + * Adjusts the offset by the width of the current code point, either 1 or 2 chars. + */ + void adjustOffsetByCodePoint(); + + void setLength(int32_t length); + + void resetLength(); + + int32_t length() const; + + char16_t charAt(int32_t index) const; + + UChar32 codePointAt(int32_t index) const; + + UnicodeString toUnicodeString() const; + + const UnicodeString toTempUnicodeString() const; + + /** + * Returns the first code point in the string segment, or -1 if the string starts with an invalid + * code point. + * + * <p> + * <strong>Important:</strong> Most of the time, you should use {@link #startsWith}, which handles case + * folding logic, instead of this method. + */ + UChar32 getCodePoint() const; + + /** + * Returns true if the first code point of this StringSegment equals the given code point. + * + * <p> + * This method will perform case folding if case folding is enabled for the parser. + */ + bool startsWith(UChar32 otherCp) const; + + /** + * Returns true if the first code point of this StringSegment is in the given UnicodeSet. + */ + bool startsWith(const UnicodeSet& uniset) const; + + /** + * Returns true if there is at least one code point of overlap between this StringSegment and the + * given UnicodeString. + */ + bool startsWith(const UnicodeString& other) const; + + /** + * Returns the length of the prefix shared by this StringSegment and the given UnicodeString. For + * example, if this string segment is "aab", and the char sequence is "aac", this method returns 2, + * since the first 2 characters are the same. + * + * <p> + * This method only returns offsets along code point boundaries. + * + * <p> + * This method will perform case folding if case folding was enabled in the constructor. + * + * <p> + * IMPORTANT: The given UnicodeString must not be empty! It is the caller's responsibility to check. + */ + int32_t getCommonPrefixLength(const UnicodeString& other); + + /** + * Like {@link #getCommonPrefixLength}, but never performs case folding, even if case folding is + * enabled for the parser. + */ + int32_t getCaseSensitivePrefixLength(const UnicodeString& other); + + bool operator==(const UnicodeString& other) const; + + private: + const UnicodeString& fStr; + int32_t fStart; + int32_t fEnd; + bool fFoldCase; + + int32_t getPrefixLengthInternal(const UnicodeString& other, bool foldCase); + + static bool codePointsEqual(UChar32 cp1, UChar32 cp2, bool foldCase); +}; + + +U_NAMESPACE_END + +#endif //__NUMPARSE_STRINGSEGMENT_H__ +#endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/strmatch.cpp b/deps/icu-small/source/i18n/strmatch.cpp index d5b018aa6b..97c0fba6f1 100644 --- a/deps/icu-small/source/i18n/strmatch.cpp +++ b/deps/icu-small/source/i18n/strmatch.cpp @@ -58,7 +58,7 @@ StringMatcher::~StringMatcher() { /** * Implement UnicodeFunctor */ -UnicodeFunctor* StringMatcher::clone() const { +StringMatcher* StringMatcher::clone() const { return new StringMatcher(*this); } diff --git a/deps/icu-small/source/i18n/strmatch.h b/deps/icu-small/source/i18n/strmatch.h index 7152a24a07..09d04ede13 100644 --- a/deps/icu-small/source/i18n/strmatch.h +++ b/deps/icu-small/source/i18n/strmatch.h @@ -78,7 +78,7 @@ class StringMatcher : public UnicodeFunctor, public UnicodeMatcher, public Unico * Implement UnicodeFunctor * @return a copy of the object. */ - virtual UnicodeFunctor* clone() const; + virtual StringMatcher* clone() const; /** * UnicodeFunctor API. Cast 'this' to a UnicodeMatcher* pointer diff --git a/deps/icu-small/source/i18n/strrepl.cpp b/deps/icu-small/source/i18n/strrepl.cpp index 132c844c2d..e9e71ee540 100644 --- a/deps/icu-small/source/i18n/strrepl.cpp +++ b/deps/icu-small/source/i18n/strrepl.cpp @@ -87,7 +87,7 @@ StringReplacer::~StringReplacer() { /** * Implement UnicodeFunctor */ -UnicodeFunctor* StringReplacer::clone() const { +StringReplacer* StringReplacer::clone() const { return new StringReplacer(*this); } diff --git a/deps/icu-small/source/i18n/strrepl.h b/deps/icu-small/source/i18n/strrepl.h index feec058152..7f74d0d945 100644 --- a/deps/icu-small/source/i18n/strrepl.h +++ b/deps/icu-small/source/i18n/strrepl.h @@ -111,7 +111,7 @@ class StringReplacer : public UnicodeFunctor, public UnicodeReplacer { /** * Implement UnicodeFunctor */ - virtual UnicodeFunctor* clone() const; + virtual StringReplacer* clone() const; /** * UnicodeFunctor API. Cast 'this' to a UnicodeReplacer* pointer diff --git a/deps/icu-small/source/i18n/stsearch.cpp b/deps/icu-small/source/i18n/stsearch.cpp index bf4d80b6db..32481a1400 100644 --- a/deps/icu-small/source/i18n/stsearch.cpp +++ b/deps/icu-small/source/i18n/stsearch.cpp @@ -282,7 +282,7 @@ void StringSearch::reset() usearch_reset(m_strsrch_); } -SearchIterator * StringSearch::safeClone(void) const +StringSearch * StringSearch::safeClone() const { UErrorCode status = U_ZERO_ERROR; StringSearch *result = new StringSearch(m_pattern_, m_text_, diff --git a/deps/icu-small/source/i18n/taiwncal.cpp b/deps/icu-small/source/i18n/taiwncal.cpp index e2757dbd55..1a6a0e2e78 100644 --- a/deps/icu-small/source/i18n/taiwncal.cpp +++ b/deps/icu-small/source/i18n/taiwncal.cpp @@ -53,7 +53,7 @@ TaiwanCalendar& TaiwanCalendar::operator= ( const TaiwanCalendar& right) return *this; } -Calendar* TaiwanCalendar::clone(void) const +TaiwanCalendar* TaiwanCalendar::clone() const { return new TaiwanCalendar(*this); } diff --git a/deps/icu-small/source/i18n/taiwncal.h b/deps/icu-small/source/i18n/taiwncal.h index 99bbfb53f2..daadc124f4 100644 --- a/deps/icu-small/source/i18n/taiwncal.h +++ b/deps/icu-small/source/i18n/taiwncal.h @@ -91,7 +91,7 @@ public: * @return return a polymorphic copy of this calendar. * @internal */ - virtual Calendar* clone(void) const; + virtual TaiwanCalendar* clone() const; public: /** diff --git a/deps/icu-small/source/i18n/timezone.cpp b/deps/icu-small/source/i18n/timezone.cpp index 70169b5c1f..b90b78614a 100644 --- a/deps/icu-small/source/i18n/timezone.cpp +++ b/deps/icu-small/source/i18n/timezone.cpp @@ -527,6 +527,8 @@ TimeZone::detectHostTimeZone() // ------------------------------------- +static UMutex gDefaultZoneMutex; + /** * Initialize DEFAULT_ZONE from the system default time zone. * Upon return, DEFAULT_ZONE will not be NULL, unless operator new() @@ -536,6 +538,7 @@ static void U_CALLCONV initDefault() { ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup); + Mutex lock(&gDefaultZoneMutex); // If setDefault() has already been called we can skip getting the // default zone information from the system. if (DEFAULT_ZONE != NULL) { @@ -557,9 +560,6 @@ static void U_CALLCONV initDefault() TimeZone *default_zone = TimeZone::detectHostTimeZone(); - // The only way for DEFAULT_ZONE to be non-null at this point is if the user - // made a thread-unsafe call to setDefault() or adoptDefault() in another - // thread while this thread was doing something that required getting the default. U_ASSERT(DEFAULT_ZONE == NULL); DEFAULT_ZONE = default_zone; @@ -571,7 +571,10 @@ TimeZone* U_EXPORT2 TimeZone::createDefault() { umtx_initOnce(gDefaultZoneInitOnce, initDefault); - return (DEFAULT_ZONE != NULL) ? DEFAULT_ZONE->clone() : NULL; + { + Mutex lock(&gDefaultZoneMutex); + return (DEFAULT_ZONE != NULL) ? DEFAULT_ZONE->clone() : NULL; + } } // ------------------------------------- @@ -581,9 +584,12 @@ TimeZone::adoptDefault(TimeZone* zone) { if (zone != NULL) { - TimeZone *old = DEFAULT_ZONE; - DEFAULT_ZONE = zone; - delete old; + { + Mutex lock(&gDefaultZoneMutex); + TimeZone *old = DEFAULT_ZONE; + DEFAULT_ZONE = zone; + delete old; + } ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup); } } diff --git a/deps/icu-small/source/i18n/titletrn.cpp b/deps/icu-small/source/i18n/titletrn.cpp index 4e75c824a0..a6beac2149 100644 --- a/deps/icu-small/source/i18n/titletrn.cpp +++ b/deps/icu-small/source/i18n/titletrn.cpp @@ -60,7 +60,7 @@ TitlecaseTransliterator::TitlecaseTransliterator(const TitlecaseTransliterator& /** * Transliterator API. */ -Transliterator* TitlecaseTransliterator::clone(void) const { +TitlecaseTransliterator* TitlecaseTransliterator::clone() const { return new TitlecaseTransliterator(*this); } diff --git a/deps/icu-small/source/i18n/titletrn.h b/deps/icu-small/source/i18n/titletrn.h index 166378fe9d..4e45ac6f81 100644 --- a/deps/icu-small/source/i18n/titletrn.h +++ b/deps/icu-small/source/i18n/titletrn.h @@ -52,7 +52,7 @@ class TitlecaseTransliterator : public CaseMapTransliterator { * Transliterator API. * @return a copy of the object. */ - virtual Transliterator* clone(void) const; + virtual TitlecaseTransliterator* clone() const; /** * ICU "poor man's RTTI", returns a UClassID for the actual class. diff --git a/deps/icu-small/source/i18n/tmunit.cpp b/deps/icu-small/source/i18n/tmunit.cpp index 3e98010515..b96dfbb572 100644 --- a/deps/icu-small/source/i18n/tmunit.cpp +++ b/deps/icu-small/source/i18n/tmunit.cpp @@ -102,7 +102,7 @@ TimeUnit::TimeUnit(const TimeUnit& other) : MeasureUnit(other), fTimeUnitField(other.fTimeUnitField) { } -UObject* +TimeUnit* TimeUnit::clone() const { return new TimeUnit(*this); } diff --git a/deps/icu-small/source/i18n/tmutamt.cpp b/deps/icu-small/source/i18n/tmutamt.cpp index 0e2b91fbb2..a143bcf8f7 100644 --- a/deps/icu-small/source/i18n/tmutamt.cpp +++ b/deps/icu-small/source/i18n/tmutamt.cpp @@ -50,7 +50,7 @@ TimeUnitAmount::operator==(const UObject& other) const { return Measure::operator==(other); } -UObject* +TimeUnitAmount* TimeUnitAmount::clone() const { return new TimeUnitAmount(*this); } diff --git a/deps/icu-small/source/i18n/tmutfmt.cpp b/deps/icu-small/source/i18n/tmutfmt.cpp index dad8825e70..231ea5799c 100644 --- a/deps/icu-small/source/i18n/tmutfmt.cpp +++ b/deps/icu-small/source/i18n/tmutfmt.cpp @@ -136,8 +136,8 @@ TimeUnitFormat::~TimeUnitFormat() { } -Format* -TimeUnitFormat::clone(void) const { +TimeUnitFormat* +TimeUnitFormat::clone() const { return new TimeUnitFormat(*this); } @@ -685,7 +685,7 @@ TimeUnitFormat::setNumberFormat(const NumberFormat& format, UErrorCode& status){ if (U_FAILURE(status)) { return; } - adoptNumberFormat((NumberFormat *)format.clone(), status); + adoptNumberFormat(format.clone(), status); } @@ -721,8 +721,8 @@ TimeUnitFormat::copyHash(const Hashtable* source, Hashtable* target, UErrorCode& const UHashTok valueTok = element->value; const MessageFormat** value = (const MessageFormat**)valueTok.pointer; MessageFormat** newVal = (MessageFormat**)uprv_malloc(UTMUTFMT_FORMAT_STYLE_COUNT*sizeof(MessageFormat*)); - newVal[0] = (MessageFormat*)value[0]->clone(); - newVal[1] = (MessageFormat*)value[1]->clone(); + newVal[0] = value[0]->clone(); + newVal[1] = value[1]->clone(); target->put(UnicodeString(*key), newVal, status); if ( U_FAILURE(status) ) { delete newVal[0]; diff --git a/deps/icu-small/source/i18n/tolowtrn.cpp b/deps/icu-small/source/i18n/tolowtrn.cpp index 063cc88d1c..02ec05cd52 100644 --- a/deps/icu-small/source/i18n/tolowtrn.cpp +++ b/deps/icu-small/source/i18n/tolowtrn.cpp @@ -58,7 +58,7 @@ LowercaseTransliterator::LowercaseTransliterator(const LowercaseTransliterator& /** * Transliterator API. */ -Transliterator* LowercaseTransliterator::clone(void) const { +LowercaseTransliterator* LowercaseTransliterator::clone() const { return new LowercaseTransliterator(*this); } diff --git a/deps/icu-small/source/i18n/tolowtrn.h b/deps/icu-small/source/i18n/tolowtrn.h index e311431224..2fbfb90e1b 100644 --- a/deps/icu-small/source/i18n/tolowtrn.h +++ b/deps/icu-small/source/i18n/tolowtrn.h @@ -50,7 +50,7 @@ class LowercaseTransliterator : public CaseMapTransliterator { * Transliterator API. * @return a copy of the object. */ - virtual Transliterator* clone(void) const; + virtual LowercaseTransliterator* clone() const; /** * ICU "poor man's RTTI", returns a UClassID for the actual class. diff --git a/deps/icu-small/source/i18n/toupptrn.cpp b/deps/icu-small/source/i18n/toupptrn.cpp index 098dba9a3c..2a8b78b9a6 100644 --- a/deps/icu-small/source/i18n/toupptrn.cpp +++ b/deps/icu-small/source/i18n/toupptrn.cpp @@ -58,7 +58,7 @@ UppercaseTransliterator::UppercaseTransliterator(const UppercaseTransliterator& /** * Transliterator API. */ -Transliterator* UppercaseTransliterator::clone(void) const { +UppercaseTransliterator* UppercaseTransliterator::clone() const { return new UppercaseTransliterator(*this); } diff --git a/deps/icu-small/source/i18n/toupptrn.h b/deps/icu-small/source/i18n/toupptrn.h index 677a04e5c7..e96ca8f0ba 100644 --- a/deps/icu-small/source/i18n/toupptrn.h +++ b/deps/icu-small/source/i18n/toupptrn.h @@ -50,7 +50,7 @@ class UppercaseTransliterator : public CaseMapTransliterator { * Transliterator API. * @return a copy of the object. */ - virtual Transliterator* clone(void) const; + virtual UppercaseTransliterator* clone() const; /** * ICU "poor man's RTTI", returns a UClassID for the actual class. diff --git a/deps/icu-small/source/i18n/translit.cpp b/deps/icu-small/source/i18n/translit.cpp index 9f5563b479..039acaf157 100644 --- a/deps/icu-small/source/i18n/translit.cpp +++ b/deps/icu-small/source/i18n/translit.cpp @@ -91,10 +91,7 @@ static const char RB_RULE_BASED_IDS[] = "RuleBasedTransliteratorIDs"; /** * The mutex controlling access to registry object. */ -static icu::UMutex *registryMutex() { - static icu::UMutex m = U_MUTEX_INITIALIZER; - return &m; -} +static icu::UMutex registryMutex; /** * System transliterator registry; non-null when initialized. @@ -161,7 +158,7 @@ Transliterator::Transliterator(const Transliterator& other) : if (other.filter != 0) { // We own the filter, so we must have our own copy - filter = (UnicodeFilter*) other.filter->clone(); + filter = other.filter->clone(); } } @@ -178,7 +175,7 @@ Transliterator& Transliterator::operator=(const Transliterator& other) { ID.getTerminatedBuffer(); maximumContextLength = other.maximumContextLength; - adoptFilter((other.filter == 0) ? 0 : (UnicodeFilter*) other.filter->clone()); + adoptFilter((other.filter == 0) ? 0 : other.filter->clone()); return *this; } @@ -926,13 +923,15 @@ Transliterator::createInstance(const UnicodeString& ID, return NULL; } - UnicodeSet* globalFilter; + UnicodeSet* globalFilter = nullptr; // TODO add code for parseError...currently unused, but // later may be used by parsing code... if (!TransliteratorIDParser::parseCompoundID(ID, dir, canonID, list, globalFilter)) { status = U_INVALID_ID; + delete globalFilter; return NULL; } + LocalPointer<UnicodeSet> lpGlobalFilter(globalFilter); TransliteratorIDParser::instantiateList(list, status); if (U_FAILURE(status)) { @@ -956,8 +955,8 @@ Transliterator::createInstance(const UnicodeString& ID, // Check null pointer if (t != NULL) { t->setID(canonID); - if (globalFilter != NULL) { - t->adoptFilter(globalFilter); + if (lpGlobalFilter.isValid()) { + t->adoptFilter(lpGlobalFilter.orphan()); } } else if (U_SUCCESS(status)) { @@ -981,11 +980,11 @@ Transliterator* Transliterator::createBasicInstance(const UnicodeString& id, TransliteratorAlias* alias = 0; Transliterator* t = 0; - umtx_lock(registryMutex()); + umtx_lock(®istryMutex); if (HAVE_REGISTRY(ec)) { t = registry->get(id, alias, ec); } - umtx_unlock(registryMutex()); + umtx_unlock(®istryMutex); if (U_FAILURE(ec)) { delete t; @@ -1013,11 +1012,11 @@ Transliterator* Transliterator::createBasicInstance(const UnicodeString& id, alias = 0; // Step 2. reget - umtx_lock(registryMutex()); + umtx_lock(®istryMutex); if (HAVE_REGISTRY(ec)) { t = registry->reget(id, parser, alias, ec); } - umtx_unlock(registryMutex()); + umtx_unlock(®istryMutex); // Step 3. Loop back around! } else { @@ -1104,6 +1103,10 @@ Transliterator::createFromRules(const UnicodeString& ID, UnicodeString* idBlock = (UnicodeString*)parser.idBlockVector.elementAt(i); if (!idBlock->isEmpty()) { Transliterator* temp = createInstance(*idBlock, UTRANS_FORWARD, parseError, status); + if (U_FAILURE(status)) { + delete temp; + return nullptr; + } if (temp != NULL && typeid(*temp) != typeid(NullTransliterator)) transliterators.addElement(temp, status); else @@ -1117,8 +1120,10 @@ Transliterator::createFromRules(const UnicodeString& ID, data, TRUE); // Check if NULL before adding it to transliterators to avoid future usage of NULL pointer. if (temprbt == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - return t; + if (U_SUCCESS(status)) { + status = U_MEMORY_ALLOCATION_ERROR; + } + return t; } transliterators.addElement(temprbt, status); } @@ -1215,7 +1220,7 @@ UnicodeSet& Transliterator::getTargetSet(UnicodeSet& result) const { void U_EXPORT2 Transliterator::registerFactory(const UnicodeString& id, Transliterator::Factory factory, Transliterator::Token context) { - Mutex lock(registryMutex()); + Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { _registerFactory(id, factory, context); @@ -1254,7 +1259,7 @@ void Transliterator::_registerSpecialInverse(const UnicodeString& target, * @see #unregister */ void U_EXPORT2 Transliterator::registerInstance(Transliterator* adoptedPrototype) { - Mutex lock(registryMutex()); + Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { _registerInstance(adoptedPrototype); @@ -1268,7 +1273,7 @@ void Transliterator::_registerInstance(Transliterator* adoptedPrototype) { void U_EXPORT2 Transliterator::registerAlias(const UnicodeString& aliasID, const UnicodeString& realID) { - Mutex lock(registryMutex()); + Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { _registerAlias(aliasID, realID); @@ -1290,7 +1295,7 @@ void Transliterator::_registerAlias(const UnicodeString& aliasID, */ void U_EXPORT2 Transliterator::unregister(const UnicodeString& ID) { - Mutex lock(registryMutex()); + Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { registry->remove(ID); @@ -1305,7 +1310,7 @@ void U_EXPORT2 Transliterator::unregister(const UnicodeString& ID) { */ int32_t U_EXPORT2 Transliterator::countAvailableIDs(void) { int32_t retVal = 0; - Mutex lock(registryMutex()); + Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { retVal = registry->countAvailableIDs(); @@ -1321,12 +1326,12 @@ int32_t U_EXPORT2 Transliterator::countAvailableIDs(void) { */ const UnicodeString& U_EXPORT2 Transliterator::getAvailableID(int32_t index) { const UnicodeString* result = NULL; - umtx_lock(registryMutex()); + umtx_lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { result = ®istry->getAvailableID(index); } - umtx_unlock(registryMutex()); + umtx_unlock(®istryMutex); U_ASSERT(result != NULL); // fail if no registry return *result; } @@ -1334,11 +1339,11 @@ const UnicodeString& U_EXPORT2 Transliterator::getAvailableID(int32_t index) { StringEnumeration* U_EXPORT2 Transliterator::getAvailableIDs(UErrorCode& ec) { if (U_FAILURE(ec)) return NULL; StringEnumeration* result = NULL; - umtx_lock(registryMutex()); + umtx_lock(®istryMutex); if (HAVE_REGISTRY(ec)) { result = registry->getAvailableIDs(); } - umtx_unlock(registryMutex()); + umtx_unlock(®istryMutex); if (result == NULL) { ec = U_INTERNAL_TRANSLITERATOR_ERROR; } @@ -1346,14 +1351,14 @@ StringEnumeration* U_EXPORT2 Transliterator::getAvailableIDs(UErrorCode& ec) { } int32_t U_EXPORT2 Transliterator::countAvailableSources(void) { - Mutex lock(registryMutex()); + Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; return HAVE_REGISTRY(ec) ? _countAvailableSources() : 0; } UnicodeString& U_EXPORT2 Transliterator::getAvailableSource(int32_t index, UnicodeString& result) { - Mutex lock(registryMutex()); + Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { _getAvailableSource(index, result); @@ -1362,7 +1367,7 @@ UnicodeString& U_EXPORT2 Transliterator::getAvailableSource(int32_t index, } int32_t U_EXPORT2 Transliterator::countAvailableTargets(const UnicodeString& source) { - Mutex lock(registryMutex()); + Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; return HAVE_REGISTRY(ec) ? _countAvailableTargets(source) : 0; } @@ -1370,7 +1375,7 @@ int32_t U_EXPORT2 Transliterator::countAvailableTargets(const UnicodeString& sou UnicodeString& U_EXPORT2 Transliterator::getAvailableTarget(int32_t index, const UnicodeString& source, UnicodeString& result) { - Mutex lock(registryMutex()); + Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { _getAvailableTarget(index, source, result); @@ -1380,7 +1385,7 @@ UnicodeString& U_EXPORT2 Transliterator::getAvailableTarget(int32_t index, int32_t U_EXPORT2 Transliterator::countAvailableVariants(const UnicodeString& source, const UnicodeString& target) { - Mutex lock(registryMutex()); + Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; return HAVE_REGISTRY(ec) ? _countAvailableVariants(source, target) : 0; } @@ -1389,7 +1394,7 @@ UnicodeString& U_EXPORT2 Transliterator::getAvailableVariant(int32_t index, const UnicodeString& source, const UnicodeString& target, UnicodeString& result) { - Mutex lock(registryMutex()); + Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { _getAvailableVariant(index, source, target, result); diff --git a/deps/icu-small/source/i18n/transreg.cpp b/deps/icu-small/source/i18n/transreg.cpp index 032a73fd14..8c90effcc2 100644 --- a/deps/icu-small/source/i18n/transreg.cpp +++ b/deps/icu-small/source/i18n/transreg.cpp @@ -131,7 +131,7 @@ Transliterator* TransliteratorAlias::create(UParseError& pe, return 0; } if (compoundFilter != 0) - t->adoptFilter((UnicodeSet*)compoundFilter->clone()); + t->adoptFilter(compoundFilter->clone()); break; case COMPOUND: { @@ -173,8 +173,8 @@ Transliterator* TransliteratorAlias::create(UParseError& pe, if (U_SUCCESS(ec)) { t = new CompoundTransliterator(ID, transliterators, - (compoundFilter ? (UnicodeSet*)(compoundFilter->clone()) : 0), - anonymousRBTs, pe, ec); + (compoundFilter ? compoundFilter->clone() : nullptr), + anonymousRBTs, pe, ec); if (t == 0) { ec = U_MEMORY_ALLOCATION_ERROR; return 0; @@ -946,7 +946,7 @@ void TransliteratorRegistry::registerEntry(const UnicodeString& ID, if (visible) { registerSTV(source, target, variant); if (!availableIDs.contains((void*) &ID)) { - UnicodeString *newID = (UnicodeString *)ID.clone(); + UnicodeString *newID = ID.clone(); // Check to make sure newID was created. if (newID != NULL) { // NUL-terminate the ID string diff --git a/deps/icu-small/source/i18n/tridpars.cpp b/deps/icu-small/source/i18n/tridpars.cpp index cbfdf03c42..eb6c6bbba3 100644 --- a/deps/icu-small/source/i18n/tridpars.cpp +++ b/deps/icu-small/source/i18n/tridpars.cpp @@ -50,10 +50,7 @@ static UInitOnce gSpecialInversesInitOnce = U_INITONCE_INITIALIZER; /** * The mutex controlling access to SPECIAL_INVERSES */ -static UMutex *LOCK() { - static UMutex m = U_MUTEX_INITIALIZER; - return &m; -} +static UMutex LOCK; TransliteratorIDParser::Specs::Specs(const UnicodeString& s, const UnicodeString& t, const UnicodeString& v, UBool sawS, @@ -297,6 +294,7 @@ UnicodeSet* TransliteratorIDParser::parseGlobalFilter(const UnicodeString& id, i pos = ppos.getIndex(); if (withParens == 1 && !ICU_Utility::parseChar(id, pos, CLOSE_REV)) { + delete filter; pos = start; return NULL; } @@ -662,7 +660,7 @@ void TransliteratorIDParser::registerSpecialInverse(const UnicodeString& target, bidirectional = FALSE; } - Mutex lock(LOCK()); + Mutex lock(&LOCK); UnicodeString *tempus = new UnicodeString(inverseTarget); // Used for null pointer check before usage. if (tempus == NULL) { @@ -866,9 +864,9 @@ TransliteratorIDParser::specsToSpecialInverse(const Specs& specs, UErrorCode &st UnicodeString* inverseTarget; - umtx_lock(LOCK()); + umtx_lock(&LOCK); inverseTarget = (UnicodeString*) SPECIAL_INVERSES->get(specs.target); - umtx_unlock(LOCK()); + umtx_unlock(&LOCK); if (inverseTarget != NULL) { // If the original ID contained "Any-" then make the diff --git a/deps/icu-small/source/i18n/tzfmt.cpp b/deps/icu-small/source/i18n/tzfmt.cpp index c948c5f5e7..267d507aa7 100644 --- a/deps/icu-small/source/i18n/tzfmt.cpp +++ b/deps/icu-small/source/i18n/tzfmt.cpp @@ -19,12 +19,15 @@ #include "unicode/udat.h" #include "unicode/ustring.h" #include "unicode/utf16.h" +#include "bytesinkutil.h" +#include "charstr.h" #include "tzgnames.h" #include "cmemory.h" #include "cstring.h" #include "putilimp.h" #include "uassert.h" #include "ucln_in.h" +#include "ulocimp.h" #include "umutex.h" #include "uresimp.h" #include "ureslocs.h" @@ -147,10 +150,7 @@ static icu::UInitOnce gZoneIdTrieInitOnce = U_INITONCE_INITIALIZER; static TextTrieMap *gShortZoneIdTrie = NULL; static icu::UInitOnce gShortZoneIdTrieInitOnce = U_INITONCE_INITIALIZER; -static UMutex *gLock() { - static UMutex m = U_MUTEX_INITIALIZER; - return &m; -} +static UMutex gLock; U_CDECL_BEGIN /** @@ -327,10 +327,13 @@ TimeZoneFormat::TimeZoneFormat(const Locale& locale, UErrorCode& status) const char* region = fLocale.getCountry(); int32_t regionLen = static_cast<int32_t>(uprv_strlen(region)); if (regionLen == 0) { - char loc[ULOC_FULLNAME_CAPACITY]; - uloc_addLikelySubtags(fLocale.getName(), loc, sizeof(loc), &status); + CharString loc; + { + CharStringByteSink sink(&loc); + ulocimp_addLikelySubtags(fLocale.getName(), sink, &status); + } - regionLen = uloc_getCountry(loc, fTargetRegion, sizeof(fTargetRegion), &status); + regionLen = uloc_getCountry(loc.data(), fTargetRegion, sizeof(fTargetRegion), &status); if (U_SUCCESS(status)) { fTargetRegion[regionLen] = 0; } else { @@ -502,7 +505,7 @@ TimeZoneFormat::operator==(const Format& other) const { return isEqual; } -Format* +TimeZoneFormat* TimeZoneFormat::clone() const { return new TimeZoneFormat(*this); } @@ -1385,12 +1388,12 @@ TimeZoneFormat::getTimeZoneGenericNames(UErrorCode& status) const { return NULL; } - umtx_lock(gLock()); + umtx_lock(&gLock); if (fTimeZoneGenericNames == NULL) { TimeZoneFormat *nonConstThis = const_cast<TimeZoneFormat *>(this); nonConstThis->fTimeZoneGenericNames = TimeZoneGenericNames::createInstance(fLocale, status); } - umtx_unlock(gLock()); + umtx_unlock(&gLock); return fTimeZoneGenericNames; } @@ -1401,7 +1404,7 @@ TimeZoneFormat::getTZDBTimeZoneNames(UErrorCode& status) const { return NULL; } - umtx_lock(gLock()); + umtx_lock(&gLock); if (fTZDBTimeZoneNames == NULL) { TZDBTimeZoneNames *tzdbNames = new TZDBTimeZoneNames(fLocale); if (tzdbNames == NULL) { @@ -1411,7 +1414,7 @@ TimeZoneFormat::getTZDBTimeZoneNames(UErrorCode& status) const { nonConstThis->fTZDBTimeZoneNames = tzdbNames; } } - umtx_unlock(gLock()); + umtx_unlock(&gLock); return fTZDBTimeZoneNames; } @@ -1875,7 +1878,7 @@ TimeZoneFormat::parseOffsetFieldsWithPattern(const UnicodeString& text, int32_t while (len > 0) { UChar32 ch; int32_t chLen; - U16_GET(patStr, 0, 0, len, ch) + U16_GET(patStr, 0, 0, len, ch); if (PatternProps::isWhiteSpace(ch)) { chLen = U16_LENGTH(ch); len -= chLen; diff --git a/deps/icu-small/source/i18n/tzgnames.cpp b/deps/icu-small/source/i18n/tzgnames.cpp index 4e3ecb4c60..e056461dc3 100644 --- a/deps/icu-small/source/i18n/tzgnames.cpp +++ b/deps/icu-small/source/i18n/tzgnames.cpp @@ -21,12 +21,15 @@ #include "unicode/strenum.h" #include "unicode/vtzone.h" +#include "bytesinkutil.h" +#include "charstr.h" #include "cmemory.h" #include "cstring.h" #include "mutex.h" #include "uhash.h" #include "uassert.h" #include "umutex.h" +#include "ulocimp.h" #include "uresimp.h" #include "ureslocs.h" #include "zonemeta.h" @@ -269,10 +272,7 @@ GNameSearchHandler::getMatches(int32_t& maxMatchLen) { return results; } -static UMutex *gLock() { - static UMutex m = U_MUTEX_INITIALIZER; - return &m; -} +static UMutex gLock; class TZGNCore : public UMemory { public: @@ -412,10 +412,13 @@ TZGNCore::initialize(const Locale& locale, UErrorCode& status) { const char* region = fLocale.getCountry(); int32_t regionLen = static_cast<int32_t>(uprv_strlen(region)); if (regionLen == 0) { - char loc[ULOC_FULLNAME_CAPACITY]; - uloc_addLikelySubtags(fLocale.getName(), loc, sizeof(loc), &status); + CharString loc; + { + CharStringByteSink sink(&loc); + ulocimp_addLikelySubtags(fLocale.getName(), sink, &status); + } - regionLen = uloc_getCountry(loc, fTargetRegion, sizeof(fTargetRegion), &status); + regionLen = uloc_getCountry(loc.data(), fTargetRegion, sizeof(fTargetRegion), &status); if (U_SUCCESS(status)) { fTargetRegion[regionLen] = 0; } else { @@ -488,11 +491,11 @@ TZGNCore::getGenericLocationName(const UnicodeString& tzCanonicalID, UnicodeStri const UChar *locname = NULL; TZGNCore *nonConstThis = const_cast<TZGNCore *>(this); - umtx_lock(gLock()); + umtx_lock(&gLock); { locname = nonConstThis->getGenericLocationName(tzCanonicalID); } - umtx_unlock(gLock()); + umtx_unlock(&gLock); if (locname == NULL) { name.setToBogus(); @@ -743,11 +746,11 @@ TZGNCore::getPartialLocationName(const UnicodeString& tzCanonicalID, const UChar *uplname = NULL; TZGNCore *nonConstThis = const_cast<TZGNCore *>(this); - umtx_lock(gLock()); + umtx_lock(&gLock); { uplname = nonConstThis->getPartialLocationName(tzCanonicalID, mzID, isLong, mzDisplayName); } - umtx_unlock(gLock()); + umtx_unlock(&gLock); if (uplname == NULL) { name.setToBogus(); @@ -1010,11 +1013,11 @@ TZGNCore::findLocal(const UnicodeString& text, int32_t start, uint32_t types, UE TZGNCore *nonConstThis = const_cast<TZGNCore *>(this); - umtx_lock(gLock()); + umtx_lock(&gLock); { fGNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status); } - umtx_unlock(gLock()); + umtx_unlock(&gLock); if (U_FAILURE(status)) { return NULL; @@ -1041,7 +1044,7 @@ TZGNCore::findLocal(const UnicodeString& text, int32_t start, uint32_t types, UE // All names are not yet loaded into the local trie. // Load all available names into the trie. This could be very heavy. - umtx_lock(gLock()); + umtx_lock(&gLock); { if (!fGNamesTrieFullyLoaded) { StringEnumeration *tzIDs = TimeZone::createTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, NULL, NULL, status); @@ -1063,18 +1066,18 @@ TZGNCore::findLocal(const UnicodeString& text, int32_t start, uint32_t types, UE } } } - umtx_unlock(gLock()); + umtx_unlock(&gLock); if (U_FAILURE(status)) { return NULL; } - umtx_lock(gLock()); + umtx_lock(&gLock); { // now try it again fGNamesTrie.search(text, start, (TextTrieMapSearchResultHandler *)&handler, status); } - umtx_unlock(gLock()); + umtx_unlock(&gLock); results = handler.getMatches(maxLen); if (results != NULL && maxLen > 0) { @@ -1115,10 +1118,7 @@ typedef struct TZGNCoreRef { } TZGNCoreRef; // TZGNCore object cache handling -static UMutex *gTZGNLock() { - static UMutex m = U_MUTEX_INITIALIZER; - return &m; -} +static UMutex gTZGNLock; static UHashtable *gTZGNCoreCache = NULL; static UBool gTZGNCoreCacheInitialized = FALSE; @@ -1184,13 +1184,13 @@ TimeZoneGenericNames::TimeZoneGenericNames() } TimeZoneGenericNames::~TimeZoneGenericNames() { - umtx_lock(gTZGNLock()); + umtx_lock(&gTZGNLock); { U_ASSERT(fRef->refCount > 0); // Just decrement the reference count fRef->refCount--; } - umtx_unlock(gTZGNLock()); + umtx_unlock(&gTZGNLock); } TimeZoneGenericNames* @@ -1206,7 +1206,7 @@ TimeZoneGenericNames::createInstance(const Locale& locale, UErrorCode& status) { TZGNCoreRef *cacheEntry = NULL; { - Mutex lock(gTZGNLock()); + Mutex lock(&gTZGNLock); if (!gTZGNCoreCacheInitialized) { // Create empty hashtable @@ -1298,13 +1298,13 @@ TimeZoneGenericNames* TimeZoneGenericNames::clone() const { TimeZoneGenericNames* other = new TimeZoneGenericNames(); if (other) { - umtx_lock(gTZGNLock()); + umtx_lock(&gTZGNLock); { // Just increments the reference count fRef->refCount++; other->fRef = fRef; } - umtx_unlock(gTZGNLock()); + umtx_unlock(&gTZGNLock); } return other; } diff --git a/deps/icu-small/source/i18n/tznames.cpp b/deps/icu-small/source/i18n/tznames.cpp index acd6aecdc0..d789c12363 100644 --- a/deps/icu-small/source/i18n/tznames.cpp +++ b/deps/icu-small/source/i18n/tznames.cpp @@ -29,10 +29,7 @@ U_NAMESPACE_BEGIN // TimeZoneNames object cache handling -static UMutex *gTimeZoneNamesLock() { - static UMutex m = U_MUTEX_INITIALIZER; - return &m; -} +static UMutex gTimeZoneNamesLock; static UHashtable *gTimeZoneNamesCache = NULL; static UBool gTimeZoneNamesCacheInitialized = FALSE; @@ -109,7 +106,7 @@ public: virtual UBool operator==(const TimeZoneNames& other) const; virtual UBool operator!=(const TimeZoneNames& other) const {return !operator==(other);} - virtual TimeZoneNames* clone() const; + virtual TimeZoneNamesDelegate* clone() const; StringEnumeration* getAvailableMetaZoneIDs(UErrorCode& status) const; StringEnumeration* getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const; @@ -135,7 +132,7 @@ TimeZoneNamesDelegate::TimeZoneNamesDelegate() } TimeZoneNamesDelegate::TimeZoneNamesDelegate(const Locale& locale, UErrorCode& status) { - Mutex lock(gTimeZoneNamesLock()); + Mutex lock(&gTimeZoneNamesLock); if (!gTimeZoneNamesCacheInitialized) { // Create empty hashtable if it is not already initialized. gTimeZoneNamesCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status); @@ -211,7 +208,7 @@ TimeZoneNamesDelegate::TimeZoneNamesDelegate(const Locale& locale, UErrorCode& s } TimeZoneNamesDelegate::~TimeZoneNamesDelegate() { - umtx_lock(gTimeZoneNamesLock()); + umtx_lock(&gTimeZoneNamesLock); { if (fTZnamesCacheEntry) { U_ASSERT(fTZnamesCacheEntry->refCount > 0); @@ -219,7 +216,7 @@ TimeZoneNamesDelegate::~TimeZoneNamesDelegate() { fTZnamesCacheEntry->refCount--; } } - umtx_unlock(gTimeZoneNamesLock()); + umtx_unlock(&gTimeZoneNamesLock); } UBool @@ -236,17 +233,17 @@ TimeZoneNamesDelegate::operator==(const TimeZoneNames& other) const { return FALSE; } -TimeZoneNames* +TimeZoneNamesDelegate* TimeZoneNamesDelegate::clone() const { TimeZoneNamesDelegate* other = new TimeZoneNamesDelegate(); if (other != NULL) { - umtx_lock(gTimeZoneNamesLock()); + umtx_lock(&gTimeZoneNamesLock); { // Just increment the reference count fTZnamesCacheEntry->refCount++; other->fTZnamesCacheEntry = fTZnamesCacheEntry; } - umtx_unlock(gTimeZoneNamesLock()); + umtx_unlock(&gTimeZoneNamesLock); } return other; } diff --git a/deps/icu-small/source/i18n/tznames_impl.cpp b/deps/icu-small/source/i18n/tznames_impl.cpp index d6e0ee2fbb..180b7fefbf 100644 --- a/deps/icu-small/source/i18n/tznames_impl.cpp +++ b/deps/icu-small/source/i18n/tznames_impl.cpp @@ -21,11 +21,14 @@ #include "unicode/utf16.h" #include "tznames_impl.h" +#include "bytesinkutil.h" +#include "charstr.h" #include "cmemory.h" #include "cstring.h" #include "uassert.h" #include "mutex.h" #include "resource.h" +#include "ulocimp.h" #include "uresimp.h" #include "ureslocs.h" #include "zonemeta.h" @@ -49,10 +52,7 @@ static const UChar NO_NAME[] = { 0 }; // for empty no-fallback time static const char* TZDBNAMES_KEYS[] = {"ss", "sd"}; static const int32_t TZDBNAMES_KEYS_SIZE = UPRV_LENGTHOF(TZDBNAMES_KEYS); -static UMutex *gDataMutex() { - static UMutex m = U_MUTEX_INITIALIZER; - return &m; -} +static UMutex gDataMutex; static UHashtable* gTZDBNamesMap = NULL; static icu::UInitOnce gTZDBNamesMapInitOnce = U_INITONCE_INITIALIZER; @@ -388,7 +388,7 @@ TextTrieMap::search(const UnicodeString &text, int32_t start, // Don't do unless it's really required. // Mutex for protecting the lazy creation of the Trie node structure on the first call to search(). - static UMutex TextTrieMutex = U_MUTEX_INITIALIZER; + static UMutex TextTrieMutex; Mutex lock(&TextTrieMutex); if (fLazyContents != NULL) { @@ -1113,7 +1113,7 @@ TimeZoneNamesImpl::operator==(const TimeZoneNames& other) const { return FALSE; } -TimeZoneNames* +TimeZoneNamesImpl* TimeZoneNamesImpl::clone() const { UErrorCode status = U_ZERO_ERROR; return new TimeZoneNamesImpl(fLocale, status); @@ -1214,7 +1214,7 @@ TimeZoneNamesImpl::getMetaZoneDisplayName(const UnicodeString& mzID, TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); { - Mutex lock(gDataMutex()); + Mutex lock(&gDataMutex); UErrorCode status = U_ZERO_ERROR; znames = nonConstThis->loadMetaZoneNames(mzID, status); if (U_FAILURE(status)) { return name; } @@ -1240,7 +1240,7 @@ TimeZoneNamesImpl::getTimeZoneDisplayName(const UnicodeString& tzID, UTimeZoneNa TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); { - Mutex lock(gDataMutex()); + Mutex lock(&gDataMutex); UErrorCode status = U_ZERO_ERROR; tznames = nonConstThis->loadTimeZoneNames(tzID, status); if (U_FAILURE(status)) { return name; } @@ -1263,7 +1263,7 @@ TimeZoneNamesImpl::getExemplarLocationName(const UnicodeString& tzID, UnicodeStr TimeZoneNamesImpl *nonConstThis = const_cast<TimeZoneNamesImpl *>(this); { - Mutex lock(gDataMutex()); + Mutex lock(&gDataMutex); UErrorCode status = U_ZERO_ERROR; tznames = nonConstThis->loadTimeZoneNames(tzID, status); if (U_FAILURE(status)) { return name; } @@ -1358,7 +1358,7 @@ TimeZoneNamesImpl::find(const UnicodeString& text, int32_t start, uint32_t types // Synchronize so that data is not loaded multiple times. // TODO: Consider more fine-grained synchronization. { - Mutex lock(gDataMutex()); + Mutex lock(&gDataMutex); // First try of lookup. matches = doFind(handler, text, start, status); @@ -1585,7 +1585,7 @@ void TimeZoneNamesImpl::loadAllDisplayNames(UErrorCode& status) { if (U_FAILURE(status)) return; { - Mutex lock(gDataMutex()); + Mutex lock(&gDataMutex); internalLoadAllDisplayNames(status); } } @@ -1602,7 +1602,7 @@ void TimeZoneNamesImpl::getDisplayNames(const UnicodeString& tzID, // Load the time zone strings { - Mutex lock(gDataMutex()); + Mutex lock(&gDataMutex); tznames = (void*) nonConstThis->loadTimeZoneNames(tzID, status); if (U_FAILURE(status)) { return; } } @@ -1622,7 +1622,7 @@ void TimeZoneNamesImpl::getDisplayNames(const UnicodeString& tzID, } else { // Load the meta zone strings // Mutex is scoped to the "else" statement - Mutex lock(gDataMutex()); + Mutex lock(&gDataMutex); mznames = (void*) nonConstThis->loadMetaZoneNames(mzID, status); if (U_FAILURE(status)) { return; } // Note: when the metazone doesn't exist, in Java, loadMetaZoneNames returns @@ -2135,9 +2135,12 @@ TZDBTimeZoneNames::TZDBTimeZoneNames(const Locale& locale) int32_t regionLen = static_cast<int32_t>(uprv_strlen(region)); if (regionLen == 0) { UErrorCode status = U_ZERO_ERROR; - char loc[ULOC_FULLNAME_CAPACITY]; - uloc_addLikelySubtags(fLocale.getName(), loc, sizeof(loc), &status); - regionLen = uloc_getCountry(loc, fRegion, sizeof(fRegion), &status); + CharString loc; + { + CharStringByteSink sink(&loc); + ulocimp_addLikelySubtags(fLocale.getName(), sink, &status); + } + regionLen = uloc_getCountry(loc.data(), fRegion, sizeof(fRegion), &status); if (U_SUCCESS(status) && regionLen < (int32_t)sizeof(fRegion)) { useWorld = FALSE; } @@ -2162,7 +2165,7 @@ TZDBTimeZoneNames::operator==(const TimeZoneNames& other) const { return FALSE; } -TimeZoneNames* +TZDBTimeZoneNames* TZDBTimeZoneNames::clone() const { return new TZDBTimeZoneNames(fLocale); } @@ -2247,7 +2250,7 @@ TZDBTimeZoneNames::getMetaZoneNames(const UnicodeString& mzID, UErrorCode& statu U_ASSERT(status == U_ZERO_ERROR); // already checked length above mzIDKey[mzID.length()] = 0; - static UMutex gTZDBNamesMapLock = U_MUTEX_INITIALIZER; + static UMutex gTZDBNamesMapLock; umtx_lock(&gTZDBNamesMapLock); { void *cacheVal = uhash_get(gTZDBNamesMap, mzIDKey); diff --git a/deps/icu-small/source/i18n/tznames_impl.h b/deps/icu-small/source/i18n/tznames_impl.h index 4db036e747..1286eeb80d 100644 --- a/deps/icu-small/source/i18n/tznames_impl.h +++ b/deps/icu-small/source/i18n/tznames_impl.h @@ -174,7 +174,7 @@ public: virtual ~TimeZoneNamesImpl(); virtual UBool operator==(const TimeZoneNames& other) const; - virtual TimeZoneNames* clone() const; + virtual TimeZoneNamesImpl* clone() const; StringEnumeration* getAvailableMetaZoneIDs(UErrorCode& status) const; StringEnumeration* getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const; @@ -236,7 +236,7 @@ public: virtual ~TZDBTimeZoneNames(); virtual UBool operator==(const TimeZoneNames& other) const; - virtual TimeZoneNames* clone() const; + virtual TZDBTimeZoneNames* clone() const; StringEnumeration* getAvailableMetaZoneIDs(UErrorCode& status) const; StringEnumeration* getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const; diff --git a/deps/icu-small/source/i18n/tzrule.cpp b/deps/icu-small/source/i18n/tzrule.cpp index f60a5e0dd5..c4bf386fd4 100644 --- a/deps/icu-small/source/i18n/tzrule.cpp +++ b/deps/icu-small/source/i18n/tzrule.cpp @@ -108,7 +108,7 @@ InitialTimeZoneRule::~InitialTimeZoneRule() { } InitialTimeZoneRule* -InitialTimeZoneRule::clone(void) const { +InitialTimeZoneRule::clone() const { return new InitialTimeZoneRule(*this); } diff --git a/deps/icu-small/source/i18n/ucal.cpp b/deps/icu-small/source/i18n/ucal.cpp index 4154eea83f..cca1f70cf5 100644 --- a/deps/icu-small/source/i18n/ucal.cpp +++ b/deps/icu-small/source/i18n/ucal.cpp @@ -34,7 +34,7 @@ U_NAMESPACE_USE static TimeZone* _createTimeZone(const UChar* zoneID, int32_t len, UErrorCode* ec) { TimeZone* zone = NULL; - if (ec!=NULL && U_SUCCESS(*ec)) { + if (ec != NULL && U_SUCCESS(*ec)) { // Note that if zoneID is invalid, we get back GMT. This odd // behavior is by design and goes back to the JDK. The only // failure we will see is a memory allocation failure. @@ -69,7 +69,7 @@ ucal_openCountryTimeZones(const char* country, UErrorCode* ec) { U_CAPI int32_t U_EXPORT2 ucal_getDefaultTimeZone(UChar* result, int32_t resultCapacity, UErrorCode* ec) { int32_t len = 0; - if (ec!=NULL && U_SUCCESS(*ec)) { + if (ec != NULL && U_SUCCESS(*ec)) { TimeZone* zone = TimeZone::createDefault(); if (zone == NULL) { *ec = U_MEMORY_ALLOCATION_ERROR; @@ -91,6 +91,23 @@ ucal_setDefaultTimeZone(const UChar* zoneID, UErrorCode* ec) { } } +U_DRAFT int32_t U_EXPORT2 +ucal_getHostTimeZone(UChar* result, int32_t resultCapacity, UErrorCode* ec) { + int32_t len = 0; + if (ec != NULL && U_SUCCESS(*ec)) { + TimeZone *zone = TimeZone::detectHostTimeZone(); + if (zone == NULL) { + *ec = U_MEMORY_ALLOCATION_ERROR; + } else { + UnicodeString id; + zone->getID(id); + delete zone; + len = id.extract(result, resultCapacity, *ec); + } + } + return len; +} + U_CAPI int32_t U_EXPORT2 ucal_getDSTSavings(const UChar* zoneID, UErrorCode* ec) { int32_t result = 0; @@ -140,8 +157,8 @@ ucal_open( const UChar* zoneID, if(U_FAILURE(*status)) return 0; - TimeZone* zone = (zoneID==NULL) ? TimeZone::createDefault() - : _createTimeZone(zoneID, len, status); + LocalPointer<TimeZone> zone( (zoneID==NULL) ? TimeZone::createDefault() + : _createTimeZone(zoneID, len, status), *status); if (U_FAILURE(*status)) { return NULL; @@ -157,9 +174,9 @@ ucal_open( const UChar* zoneID, if (U_FAILURE(*status)) { return NULL; } - return (UCalendar*)Calendar::createInstance(zone, Locale(localeBuf), *status); + return (UCalendar*)Calendar::createInstance(zone.orphan(), Locale(localeBuf), *status); } - return (UCalendar*)Calendar::createInstance(zone, Locale(locale), *status); + return (UCalendar*)Calendar::createInstance(zone.orphan(), Locale(locale), *status); } U_CAPI void U_EXPORT2 diff --git a/deps/icu-small/source/i18n/udat.cpp b/deps/icu-small/source/i18n/udat.cpp index b7d85cc179..da8befc9e3 100644 --- a/deps/icu-small/source/i18n/udat.cpp +++ b/deps/icu-small/source/i18n/udat.cpp @@ -167,9 +167,13 @@ udat_open(UDateFormatStyle timeStyle, } } - if(fmt == 0) { + if(fmt == nullptr) { *status = U_MEMORY_ALLOCATION_ERROR; - return 0; + return nullptr; + } + if (U_FAILURE(*status)) { + delete fmt; + return nullptr; } if(tzID != 0) { diff --git a/deps/icu-small/source/i18n/unesctrn.cpp b/deps/icu-small/source/i18n/unesctrn.cpp index fcce9528e2..604cb0a4ba 100644 --- a/deps/icu-small/source/i18n/unesctrn.cpp +++ b/deps/icu-small/source/i18n/unesctrn.cpp @@ -164,7 +164,7 @@ UnescapeTransliterator::~UnescapeTransliterator() { /** * Transliterator API. */ -Transliterator* UnescapeTransliterator::clone() const { +UnescapeTransliterator* UnescapeTransliterator::clone() const { return new UnescapeTransliterator(*this); } diff --git a/deps/icu-small/source/i18n/unesctrn.h b/deps/icu-small/source/i18n/unesctrn.h index e8e171f2bc..57dd8d32cf 100644 --- a/deps/icu-small/source/i18n/unesctrn.h +++ b/deps/icu-small/source/i18n/unesctrn.h @@ -77,7 +77,7 @@ class UnescapeTransliterator : public Transliterator { /** * Transliterator API. */ - virtual Transliterator* clone() const; + virtual UnescapeTransliterator* clone() const; /** * ICU "poor man's RTTI", returns a UClassID for the actual class. diff --git a/deps/icu-small/source/i18n/uni2name.cpp b/deps/icu-small/source/i18n/uni2name.cpp index 86d7a4904a..9df3924ae5 100644 --- a/deps/icu-small/source/i18n/uni2name.cpp +++ b/deps/icu-small/source/i18n/uni2name.cpp @@ -60,7 +60,7 @@ UnicodeNameTransliterator::UnicodeNameTransliterator(const UnicodeNameTransliter /** * Transliterator API. */ -Transliterator* UnicodeNameTransliterator::clone(void) const { +UnicodeNameTransliterator* UnicodeNameTransliterator::clone() const { return new UnicodeNameTransliterator(*this); } diff --git a/deps/icu-small/source/i18n/uni2name.h b/deps/icu-small/source/i18n/uni2name.h index 4d6eaa0a9a..99309c8e0f 100644 --- a/deps/icu-small/source/i18n/uni2name.h +++ b/deps/icu-small/source/i18n/uni2name.h @@ -48,7 +48,7 @@ class UnicodeNameTransliterator : public Transliterator { /** * Transliterator API. */ - virtual Transliterator* clone(void) const; + virtual UnicodeNameTransliterator* clone() const; /** * ICU "poor man's RTTI", returns a UClassID for the actual class. diff --git a/deps/icu-small/source/i18n/unicode/alphaindex.h b/deps/icu-small/source/i18n/unicode/alphaindex.h index dfb6110a36..fe43995fe8 100644 --- a/deps/icu-small/source/i18n/unicode/alphaindex.h +++ b/deps/icu-small/source/i18n/unicode/alphaindex.h @@ -13,6 +13,9 @@ #define INDEXCHARS_H #include "unicode/utypes.h" + +#if U_SHOW_CPLUSPLUS_API + #include "unicode/uobject.h" #include "unicode/locid.h" #include "unicode/unistr.h" @@ -757,4 +760,7 @@ private: U_NAMESPACE_END #endif // !UCONFIG_NO_COLLATION + +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif diff --git a/deps/icu-small/source/i18n/unicode/basictz.h b/deps/icu-small/source/i18n/unicode/basictz.h index eb62abaf0a..e1db2a8223 100644 --- a/deps/icu-small/source/i18n/unicode/basictz.h +++ b/deps/icu-small/source/i18n/unicode/basictz.h @@ -16,6 +16,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING #include "unicode/timezone.h" @@ -42,6 +44,14 @@ public: virtual ~BasicTimeZone(); /** + * Clones this object polymorphically. + * The caller owns the result and should delete it when done. + * @return clone, or nullptr if an error occurred + * @stable ICU 3.8 + */ + virtual BasicTimeZone* clone() const = 0; + + /** * Gets the first time zone transition after the base time. * @param base The base time. * @param inclusive Whether the base time is inclusive or not. @@ -211,6 +221,8 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // BASICTZ_H //eof diff --git a/deps/icu-small/source/i18n/unicode/calendar.h b/deps/icu-small/source/i18n/unicode/calendar.h index 023cf053f2..2a8c2935ca 100644 --- a/deps/icu-small/source/i18n/unicode/calendar.h +++ b/deps/icu-small/source/i18n/unicode/calendar.h @@ -29,6 +29,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Calendar object @@ -184,7 +186,7 @@ class BasicTimeZone; */ class U_I18N_API Calendar : public UObject { public: - +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Field IDs for date and time. Used to specify date/time fields. ERA is calendar * specific. Example ranges given are for illustration only; see specific Calendar @@ -227,6 +229,7 @@ public: FIELD_COUNT = UCAL_FIELD_COUNT // See ucal.h for other fields. #endif /* U_HIDE_DEPRECATED_API */ }; +#endif // U_FORCE_HIDE_DEPRECATED_API #ifndef U_HIDE_DEPRECATED_API /** @@ -287,7 +290,7 @@ public: * @return a polymorphic copy of this calendar. * @stable ICU 2.0 */ - virtual Calendar* clone(void) const = 0; + virtual Calendar* clone() const = 0; /** * Creates a Calendar using the default timezone and locale. Clients are responsible @@ -518,6 +521,7 @@ public: */ UBool after(const Calendar& when, UErrorCode& status) const; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * UDate Arithmetic function. Adds the specified (signed) amount of time to the given * time field, based on the calendar's rules. For example, to subtract 5 days from @@ -539,6 +543,7 @@ public: * @deprecated ICU 2.6. use add(UCalendarDateFields field, int32_t amount, UErrorCode& status) instead. */ virtual void add(EDateFields field, int32_t amount, UErrorCode& status); +#endif // U_FORCE_HIDE_DEPRECATED_API /** * UDate Arithmetic function. Adds the specified (signed) amount of time to the given @@ -632,6 +637,7 @@ public: */ inline void roll(UCalendarDateFields field, UBool up, UErrorCode& status); +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Time Field Rolling function. Rolls by the given amount on the given * time field. For example, to roll the current date up by one day, call @@ -664,6 +670,7 @@ public: * @deprecated ICU 2.6. Use roll(UCalendarDateFields field, int32_t amount, UErrorCode& status) instead. */ virtual void roll(EDateFields field, int32_t amount, UErrorCode& status); +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Time Field Rolling function. Rolls by the given amount on the given @@ -698,6 +705,7 @@ public: */ virtual void roll(UCalendarDateFields field, int32_t amount, UErrorCode& status); +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Return the difference between the given time and the time this * calendar object is set to. If this calendar is set @@ -754,6 +762,7 @@ public: * @deprecated ICU 2.6. Use fieldDifference(UDate when, UCalendarDateFields field, UErrorCode& status). */ virtual int32_t fieldDifference(UDate when, EDateFields field, UErrorCode& status); +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Return the difference between the given time and the time this @@ -1010,6 +1019,7 @@ public: */ uint8_t getMinimalDaysInFirstWeek(void) const; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Gets the minimum value for the given time field. e.g., for Gregorian * DAY_OF_MONTH, 1. @@ -1019,6 +1029,7 @@ public: * @deprecated ICU 2.6. Use getMinimum(UCalendarDateFields field) instead. */ virtual int32_t getMinimum(EDateFields field) const; +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Gets the minimum value for the given time field. e.g., for Gregorian @@ -1030,6 +1041,7 @@ public: */ virtual int32_t getMinimum(UCalendarDateFields field) const; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Gets the maximum value for the given time field. e.g. for Gregorian DAY_OF_MONTH, * 31. @@ -1039,6 +1051,7 @@ public: * @deprecated ICU 2.6. Use getMaximum(UCalendarDateFields field) instead. */ virtual int32_t getMaximum(EDateFields field) const; +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Gets the maximum value for the given time field. e.g. for Gregorian DAY_OF_MONTH, @@ -1050,6 +1063,7 @@ public: */ virtual int32_t getMaximum(UCalendarDateFields field) const; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Gets the highest minimum value for the given field if varies. Otherwise same as * getMinimum(). For Gregorian, no difference. @@ -1059,6 +1073,7 @@ public: * @deprecated ICU 2.6. Use getGreatestMinimum(UCalendarDateFields field) instead. */ virtual int32_t getGreatestMinimum(EDateFields field) const; +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Gets the highest minimum value for the given field if varies. Otherwise same as @@ -1070,6 +1085,7 @@ public: */ virtual int32_t getGreatestMinimum(UCalendarDateFields field) const; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Gets the lowest maximum value for the given field if varies. Otherwise same as * getMaximum(). e.g., for Gregorian DAY_OF_MONTH, 28. @@ -1079,6 +1095,7 @@ public: * @deprecated ICU 2.6. Use getLeastMaximum(UCalendarDateFields field) instead. */ virtual int32_t getLeastMaximum(EDateFields field) const; +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Gets the lowest maximum value for the given field if varies. Otherwise same as @@ -1895,11 +1912,13 @@ protected: */ int32_t fFields[UCAL_FIELD_COUNT]; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * The flags which tell if a specified time field for the calendar is set. * @deprecated ICU 2.8 use (fStamp[n]!=kUnset) */ UBool fIsSet[UCAL_FIELD_COUNT]; +#endif // U_FORCE_HIDE_DEPRECATED_API /** Special values of stamp[] * @stable ICU 2.0 @@ -2281,7 +2300,6 @@ private: * should only be called if this calendar is not lenient. * @see #isLenient * @see #validateField(int, int&) - * @internal */ void validateFields(UErrorCode &status); @@ -2291,7 +2309,6 @@ private: * <code>U_ILLEGAL_ARGUMENT_ERROR</code> will be set. Subclasses may * use this method in their implementation of {@link * #validateField(int, int&)}. - * @internal */ void validateField(UCalendarDateFields field, int32_t min, int32_t max, UErrorCode& status); @@ -2529,4 +2546,6 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _CALENDAR diff --git a/deps/icu-small/source/i18n/unicode/choicfmt.h b/deps/icu-small/source/i18n/unicode/choicfmt.h index c9f0f1114f..3b2f48cb1f 100644 --- a/deps/icu-small/source/i18n/unicode/choicfmt.h +++ b/deps/icu-small/source/i18n/unicode/choicfmt.h @@ -26,13 +26,14 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Choice Format. */ #if !UCONFIG_NO_FORMATTING -#ifndef U_HIDE_DEPRECATED_API #include "unicode/fieldpos.h" #include "unicode/format.h" @@ -40,6 +41,8 @@ #include "unicode/numfmt.h" #include "unicode/unistr.h" +#ifndef U_HIDE_DEPRECATED_API + U_NAMESPACE_BEGIN class MessageFormat; @@ -248,7 +251,7 @@ public: * @return a copy of this object * @deprecated ICU 49 Use MessageFormat instead, with plural and select arguments. */ - virtual Format* clone(void) const; + virtual ChoiceFormat* clone() const; /** * Returns true if the given Format objects are semantically equal. @@ -592,5 +595,7 @@ U_NAMESPACE_END #endif // U_HIDE_DEPRECATED_API #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // CHOICFMT_H //eof diff --git a/deps/icu-small/source/i18n/unicode/coleitr.h b/deps/icu-small/source/i18n/unicode/coleitr.h index bf0e1d51a4..809d435e50 100644 --- a/deps/icu-small/source/i18n/unicode/coleitr.h +++ b/deps/icu-small/source/i18n/unicode/coleitr.h @@ -35,6 +35,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_COLLATION #include "unicode/unistr.h" @@ -404,4 +406,6 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_COLLATION */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif diff --git a/deps/icu-small/source/i18n/unicode/coll.h b/deps/icu-small/source/i18n/unicode/coll.h index 653434f54c..f5564c7394 100644 --- a/deps/icu-small/source/i18n/unicode/coll.h +++ b/deps/icu-small/source/i18n/unicode/coll.h @@ -54,6 +54,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_COLLATION #include "unicode/uobject.h" @@ -204,6 +206,7 @@ public: // Cannot use #ifndef U_HIDE_DEPRECATED_API for the following, it is // used by virtual methods that cannot have that conditional. +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * LESS is returned if source string is compared to be less than target * string in the compare() method. @@ -220,6 +223,7 @@ public: EQUAL = UCOL_EQUAL, // 0 GREATER = UCOL_GREATER // 1 }; +#endif // U_FORCE_HIDE_DEPRECATED_API // Collator public destructor ----------------------------------------- @@ -265,7 +269,7 @@ public: * @return a copy of this object, owned by the caller * @stable ICU 2.0 */ - virtual Collator* clone(void) const = 0; + virtual Collator* clone() const = 0; /** * Creates the Collator object for the current default locale. @@ -323,6 +327,7 @@ public: */ static Collator* U_EXPORT2 createInstance(const Locale& loc, UErrorCode& err); +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * The comparison function compares the character data stored in two * different strings. Returns information about whether a string is less @@ -336,6 +341,7 @@ public: */ virtual EComparisonResult compare(const UnicodeString& source, const UnicodeString& target) const; +#endif // U_FORCE_HIDE_DEPRECATED_API /** * The comparison function compares the character data stored in two @@ -353,6 +359,7 @@ public: const UnicodeString& target, UErrorCode &status) const = 0; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Does the same thing as compare but limits the comparison to a specified * length @@ -368,6 +375,7 @@ public: virtual EComparisonResult compare(const UnicodeString& source, const UnicodeString& target, int32_t length) const; +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Does the same thing as compare but limits the comparison to a specified @@ -387,6 +395,7 @@ public: int32_t length, UErrorCode &status) const = 0; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * The comparison function compares the character data stored in two * different string arrays. Returns information about whether a string array @@ -423,6 +432,7 @@ public: virtual EComparisonResult compare(const char16_t* source, int32_t sourceLength, const char16_t* target, int32_t targetLength) const; +#endif // U_FORCE_HIDE_DEPRECATED_API /** * The comparison function compares the character data stored in two @@ -527,6 +537,7 @@ public: */ virtual int32_t hashCode(void) const = 0; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Gets the locale of the Collator * @@ -540,6 +551,7 @@ public: * in ICU 3.0. */ virtual Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const = 0; +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Convenience method for comparing two strings based on the collation rules. @@ -576,6 +588,7 @@ public: */ UBool equals(const UnicodeString& source, const UnicodeString& target) const; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Determines the minimum strength that will be used in comparison or * transformation. @@ -607,6 +620,7 @@ public: * @deprecated ICU 2.6 Use setAttribute(UCOL_STRENGTH...) instead */ virtual void setStrength(ECollationStrength newStrength); +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Retrieves the reordering codes for this collator. @@ -904,6 +918,7 @@ public: */ virtual UColReorderCode getMaxVariable() const; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Sets the variable top to the primary weight of the specified string. * @@ -951,6 +966,7 @@ public: * @deprecated ICU 53 Call setMaxVariable() instead. */ virtual void setVariableTop(uint32_t varTop, UErrorCode &status) = 0; +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Gets the variable top value of a Collator. @@ -972,6 +988,7 @@ public: */ virtual UnicodeSet *getTailoredSet(UErrorCode &status) const; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Same as clone(). * The base class implementation simply calls clone(). @@ -979,7 +996,8 @@ public: * @see clone() * @deprecated ICU 50 no need to have two methods for cloning */ - virtual Collator* safeClone(void) const; + virtual Collator* safeClone() const; +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Get the sort key as an array of bytes from a UnicodeString. @@ -1271,4 +1289,6 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_COLLATION */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif diff --git a/deps/icu-small/source/i18n/unicode/compactdecimalformat.h b/deps/icu-small/source/i18n/unicode/compactdecimalformat.h index 9c1e9183f4..9c1e200996 100644 --- a/deps/icu-small/source/i18n/unicode/compactdecimalformat.h +++ b/deps/icu-small/source/i18n/unicode/compactdecimalformat.h @@ -14,6 +14,9 @@ #define __COMPACT_DECIMAL_FORMAT_H__ #include "unicode/utypes.h" + +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Compatibility APIs for compact decimal number formatting. @@ -102,7 +105,7 @@ public: * @return a polymorphic copy of this CompactDecimalFormat. * @stable ICU 51 */ - Format* clone() const U_OVERRIDE; + CompactDecimalFormat* clone() const U_OVERRIDE; using DecimalFormat::format; @@ -187,5 +190,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // __COMPACT_DECIMAL_FORMAT_H__ //eof diff --git a/deps/icu-small/source/i18n/unicode/curramt.h b/deps/icu-small/source/i18n/unicode/curramt.h index 03ec856e3b..65e6619db3 100644 --- a/deps/icu-small/source/i18n/unicode/curramt.h +++ b/deps/icu-small/source/i18n/unicode/curramt.h @@ -15,6 +15,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING #include "unicode/measure.h" @@ -79,7 +81,7 @@ class U_I18N_API CurrencyAmount: public Measure { * have the same class as returned by getDynamicClassID(). * @stable ICU 3.0 */ - virtual UObject* clone() const; + virtual CurrencyAmount* clone() const; /** * Destructor @@ -129,4 +131,7 @@ inline const char16_t* CurrencyAmount::getISOCurrency() const { U_NAMESPACE_END #endif // !UCONFIG_NO_FORMATTING + +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // __CURRENCYAMOUNT_H__ diff --git a/deps/icu-small/source/i18n/unicode/currpinf.h b/deps/icu-small/source/i18n/unicode/currpinf.h index 80b0462513..1b93be0831 100644 --- a/deps/icu-small/source/i18n/unicode/currpinf.h +++ b/deps/icu-small/source/i18n/unicode/currpinf.h @@ -11,6 +11,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Currency Plural Information used by Decimal Format @@ -266,5 +268,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _CURRPINFO //eof diff --git a/deps/icu-small/source/i18n/unicode/currunit.h b/deps/icu-small/source/i18n/unicode/currunit.h index 63739c37fd..0446154e32 100644 --- a/deps/icu-small/source/i18n/unicode/currunit.h +++ b/deps/icu-small/source/i18n/unicode/currunit.h @@ -15,6 +15,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING #include "unicode/measunit.h" @@ -94,7 +96,7 @@ class U_I18N_API CurrencyUnit: public MeasureUnit { * have the same class as returned by getDynamicClassID(). * @stable ICU 3.0 */ - virtual UObject* clone() const; + virtual CurrencyUnit* clone() const; /** * Destructor @@ -140,4 +142,7 @@ inline const char16_t* CurrencyUnit::getISOCurrency() const { U_NAMESPACE_END #endif // !UCONFIG_NO_FORMATTING + +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // __CURRENCYUNIT_H__ diff --git a/deps/icu-small/source/i18n/unicode/datefmt.h b/deps/icu-small/source/i18n/unicode/datefmt.h index 13c63d9376..21217e567a 100644 --- a/deps/icu-small/source/i18n/unicode/datefmt.h +++ b/deps/icu-small/source/i18n/unicode/datefmt.h @@ -23,6 +23,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING #include "unicode/udat.h" @@ -222,6 +224,14 @@ public: virtual ~DateFormat(); /** + * Clones this object polymorphically. + * The caller owns the result and should delete it when done. + * @return clone, or nullptr if an error occurred + * @stable ICU 2.0 + */ + virtual DateFormat* clone() const = 0; + + /** * Equality operator. Returns true if the two formats have the same behavior. * @stable ICU 2.0 */ @@ -953,5 +963,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _DATEFMT //eof diff --git a/deps/icu-small/source/i18n/unicode/dcfmtsym.h b/deps/icu-small/source/i18n/unicode/dcfmtsym.h index 55e3d8a6b3..e1e0ab6b08 100644 --- a/deps/icu-small/source/i18n/unicode/dcfmtsym.h +++ b/deps/icu-small/source/i18n/unicode/dcfmtsym.h @@ -28,10 +28,12 @@ #define DCFMTSYM_H #include "unicode/utypes.h" -#include "unicode/uchar.h" + +#if U_SHOW_CPLUSPLUS_API #if !UCONFIG_NO_FORMATTING +#include "unicode/uchar.h" #include "unicode/uobject.h" #include "unicode/locid.h" #include "unicode/numsys.h" @@ -455,13 +457,11 @@ private: * to non-resource bundle strings, * then regular UnicodeString copies must be used instead of fastCopyFrom(). * - * @internal */ UnicodeString fSymbols[kFormatSymbolCount]; /** * Non-symbol variable for getConstSymbol(). Always empty. - * @internal */ UnicodeString fNoSymbol; @@ -582,5 +582,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _DCFMTSYM //eof diff --git a/deps/icu-small/source/i18n/unicode/decimfmt.h b/deps/icu-small/source/i18n/unicode/decimfmt.h index 097a38fb88..e539b9af23 100644 --- a/deps/icu-small/source/i18n/unicode/decimfmt.h +++ b/deps/icu-small/source/i18n/unicode/decimfmt.h @@ -28,6 +28,9 @@ #define DECIMFMT_H #include "unicode/utypes.h" + +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Compatibility APIs for decimal formatting. @@ -896,7 +899,7 @@ class U_I18N_API DecimalFormat : public NumberFormat { * @return a polymorphic copy of this DecimalFormat. * @stable ICU 2.0 */ - Format* clone(void) const U_OVERRIDE; + DecimalFormat* clone() const U_OVERRIDE; /** * Return true if the given Format objects are semantically equal. @@ -1331,7 +1334,6 @@ class U_I18N_API DecimalFormat : public NumberFormat { */ virtual void setMultiplier(int32_t newValue); -#ifndef U_HIDE_DRAFT_API /** * Gets the power of ten by which number should be multiplied before formatting, which * can be combined with setMultiplier() to multiply by any arbitrary decimal value. @@ -1342,7 +1344,7 @@ class U_I18N_API DecimalFormat : public NumberFormat { * This method is analogous to UNUM_SCALE in getAttribute. * * @return the current value of the power-of-ten multiplier. - * @draft ICU 62 + * @stable ICU 62 */ int32_t getMultiplierScale(void) const; @@ -1363,10 +1365,9 @@ class U_I18N_API DecimalFormat : public NumberFormat { * This method is analogous to UNUM_SCALE in setAttribute. * * @param newValue the new value of the power-of-ten multiplier. - * @draft ICU 62 + * @stable ICU 62 */ void setMultiplierScale(int32_t newValue); -#endif /* U_HIDE_DRAFT_API */ /** * Get the rounding increment. @@ -2020,12 +2021,14 @@ class U_I18N_API DecimalFormat : public NumberFormat { */ void setCurrency(const char16_t* theCurrency, UErrorCode& ec) U_OVERRIDE; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Sets the currency used to display currency amounts. See * setCurrency(const char16_t*, UErrorCode&). * @deprecated ICU 3.0. Use setCurrency(const char16_t*, UErrorCode&). */ virtual void setCurrency(const char16_t* theCurrency); +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Sets the `Currency Usage` object used to display currency. @@ -2113,22 +2116,6 @@ class U_I18N_API DecimalFormat : public NumberFormat { const number::LocalizedNumberFormatter* toNumberFormatter(UErrorCode& status) const; #endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DEPRECATED_API - /** - * Deprecated: Like {@link #toNumberFormatter(UErrorCode&) const}, - * but does not take an error code. - * - * The new signature should be used in case an error occurs while returning the - * LocalizedNumberFormatter. - * - * This old signature will be removed in ICU 65. - * - * @return A reference to an internal object. - * @deprecated ICU 64 - */ - const number::LocalizedNumberFormatter& toNumberFormatter() const; -#endif /* U_HIDE_DEPRECATED_API */ - /** * Return the class ID for this class. This is useful only for * comparing to a return value from getDynamicClassID(). For example: @@ -2216,5 +2203,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _DECIMFMT //eof diff --git a/deps/icu-small/source/i18n/unicode/dtfmtsym.h b/deps/icu-small/source/i18n/unicode/dtfmtsym.h index ed7c189846..f9ec88272b 100644 --- a/deps/icu-small/source/i18n/unicode/dtfmtsym.h +++ b/deps/icu-small/source/i18n/unicode/dtfmtsym.h @@ -22,6 +22,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING #include "unicode/calendar.h" @@ -1011,5 +1013,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _DTFMTSYM //eof diff --git a/deps/icu-small/source/i18n/unicode/dtitvfmt.h b/deps/icu-small/source/i18n/unicode/dtitvfmt.h index 42d77d041f..23fc02e2a7 100644 --- a/deps/icu-small/source/i18n/unicode/dtitvfmt.h +++ b/deps/icu-small/source/i18n/unicode/dtitvfmt.h @@ -16,6 +16,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Format and parse date interval in a language-independent manner. @@ -432,7 +434,7 @@ public: * @return A copy of the object. * @stable ICU 4.0 */ - virtual Format* clone(void) const; + virtual DateIntervalFormat* clone() const; /** * Return true if the given Format objects are semantically equal. Objects @@ -1151,5 +1153,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _DTITVFMT_H__ //eof diff --git a/deps/icu-small/source/i18n/unicode/dtitvinf.h b/deps/icu-small/source/i18n/unicode/dtitvinf.h index 65f568c070..3c666231ab 100644 --- a/deps/icu-small/source/i18n/unicode/dtitvinf.h +++ b/deps/icu-small/source/i18n/unicode/dtitvinf.h @@ -16,6 +16,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Date/Time interval patterns for formatting date/time interval @@ -195,7 +197,7 @@ public: * @return a copy of the object * @stable ICU 4.0 */ - virtual DateIntervalInfo* clone(void) const; + virtual DateIntervalInfo* clone() const; /** * Destructor. @@ -515,4 +517,6 @@ U_NAMESPACE_END #endif +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif diff --git a/deps/icu-small/source/i18n/unicode/dtptngen.h b/deps/icu-small/source/i18n/unicode/dtptngen.h index e50c01b4e3..a71938b31c 100644 --- a/deps/icu-small/source/i18n/unicode/dtptngen.h +++ b/deps/icu-small/source/i18n/unicode/dtptngen.h @@ -14,6 +14,10 @@ #ifndef __DTPTNGEN_H__ #define __DTPTNGEN_H__ +#include "unicode/utypes.h" + +#if U_SHOW_CPLUSPLUS_API + #include "unicode/datefmt.h" #include "unicode/locid.h" #include "unicode/udat.h" @@ -279,7 +283,7 @@ public: * * @param field The desired UDateTimePatternField, such as UDATPG_ERA_FIELD. * @param width The desired UDateTimePGDisplayWidth, such as UDATPG_ABBREVIATED. - * @return. The display name for field + * @return The display name for field * @stable ICU 61 */ UnicodeString getFieldDisplayName(UDateTimePatternField field, UDateTimePGDisplayWidth width) const; @@ -561,12 +565,10 @@ private: void setDateTimeFromCalendar(const Locale& locale, UErrorCode& status); void setDecimalSymbols(const Locale& locale, UErrorCode& status); UDateTimePatternField getAppendFormatNumber(const char* field) const; -#ifndef U_HIDE_DRAFT_API - // The following three have to be U_HIDE_DRAFT_API (though private) because UDateTimePGDisplayWidth is + // Note for the next 3: UDateTimePGDisplayWidth is now stable ICU 61 UDateTimePatternField getFieldAndWidthIndices(const char* key, UDateTimePGDisplayWidth* widthP) const; void setFieldDisplayName(UDateTimePatternField field, UDateTimePGDisplayWidth width, const UnicodeString& value); UnicodeString& getMutableFieldDisplayName(UDateTimePatternField field, UDateTimePGDisplayWidth width); -#endif // U_HIDE_DRAFT_API void getAppendName(UDateTimePatternField field, UnicodeString& value); UnicodeString mapSkeletonMetacharacters(const UnicodeString& patternForm, int32_t* flags, UErrorCode& status); const UnicodeString* getBestRaw(DateTimeMatcher& source, int32_t includeMask, DistanceInfo* missingFields, UErrorCode& status, const PtnSkeleton** specifiedSkeletonPtr = 0); @@ -587,4 +589,6 @@ private: U_NAMESPACE_END +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif diff --git a/deps/icu-small/source/i18n/unicode/dtrule.h b/deps/icu-small/source/i18n/unicode/dtrule.h index 24dfc69de1..dba28bf2dc 100644 --- a/deps/icu-small/source/i18n/unicode/dtrule.h +++ b/deps/icu-small/source/i18n/unicode/dtrule.h @@ -11,6 +11,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Rule for specifying date and time in an year @@ -126,7 +128,7 @@ public: * @return A copy of the object. * @stable ICU 3.8 */ - DateTimeRule* clone(void) const; + DateTimeRule* clone() const; /** * Assignment operator. @@ -248,5 +250,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // DTRULE_H //eof diff --git a/deps/icu-small/source/i18n/unicode/fieldpos.h b/deps/icu-small/source/i18n/unicode/fieldpos.h index 78561a4de7..c9849d67a3 100644 --- a/deps/icu-small/source/i18n/unicode/fieldpos.h +++ b/deps/icu-small/source/i18n/unicode/fieldpos.h @@ -26,6 +26,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: FieldPosition identifies the fields in a formatted output. @@ -290,5 +292,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _FIELDPOS //eof diff --git a/deps/icu-small/source/i18n/unicode/fmtable.h b/deps/icu-small/source/i18n/unicode/fmtable.h index a06c23dc3b..7bec4f6906 100644 --- a/deps/icu-small/source/i18n/unicode/fmtable.h +++ b/deps/icu-small/source/i18n/unicode/fmtable.h @@ -19,6 +19,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Formattable is a thin wrapper for primitive types used for formatting and parsing @@ -751,5 +753,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif //_FMTABLE //eof diff --git a/deps/icu-small/source/i18n/unicode/format.h b/deps/icu-small/source/i18n/unicode/format.h index e64cc1c6eb..28a09159bd 100644 --- a/deps/icu-small/source/i18n/unicode/format.h +++ b/deps/icu-small/source/i18n/unicode/format.h @@ -26,6 +26,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Base class for all formats. @@ -303,5 +305,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _FORMAT //eof diff --git a/deps/icu-small/source/i18n/unicode/formattedvalue.h b/deps/icu-small/source/i18n/unicode/formattedvalue.h index 2e24c8d99e..1b130bbdd9 100644 --- a/deps/icu-small/source/i18n/unicode/formattedvalue.h +++ b/deps/icu-small/source/i18n/unicode/formattedvalue.h @@ -5,8 +5,10 @@ #define __FORMATTEDVALUE_H__ #include "unicode/utypes.h" + +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING -#ifndef U_HIDE_DRAFT_API #include "unicode/appendable.h" #include "unicode/fpositer.h" @@ -24,6 +26,10 @@ U_NAMESPACE_BEGIN */ +// The following cannot have #ifndef U_HIDE_DRAFT_API because +// class FormattedValue depends on it, and FormattedValue cannot be +// hidden becauseclass FormattedNumber (stable ICU 60) depends on it. +#ifndef U_FORCE_HIDE_DRAFT_API /** * Represents a span of a string containing a given field. * @@ -52,6 +58,7 @@ class U_I18N_API ConstrainedFieldPosition : public UMemory { /** @draft ICU 64 */ ~ConstrainedFieldPosition(); +#ifndef U_HIDE_DRAFT_API /** * Resets this ConstrainedFieldPosition to its initial state, as if it were newly created: * @@ -221,17 +228,23 @@ class U_I18N_API ConstrainedFieldPosition : public UMemory { int32_t field, int32_t start, int32_t limit); +#endif /* U_HIDE_DRAFT_API */ private: int64_t fContext = 0LL; int32_t fField = 0; int32_t fStart = 0; int32_t fLimit = 0; +#ifndef U_HIDE_DRAFT_API int32_t fCategory = UFIELD_CATEGORY_UNDEFINED; +#else /* U_HIDE_DRAFT_API */ + int32_t fCategory = 0; +#endif /* U_HIDE_DRAFT_API */ int8_t fConstraint = 0; }; - +// The following cannot have #ifndef U_HIDE_DRAFT_API because +// class FormattedNumber (stable ICU 60) depends on it. /** * An abstract formatted value: a string with associated field attributes. * Many formatters format to classes implementing FormattedValue. @@ -308,10 +321,12 @@ class U_I18N_API FormattedValue /* not : public UObject because this is an inter */ virtual UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const = 0; }; - +#endif // U_FORCE_HIDE_DRAFT_API U_NAMESPACE_END -#endif /* U_HIDE_DRAFT_API */ #endif /* #if !UCONFIG_NO_FORMATTING */ + +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // __FORMATTEDVALUE_H__ diff --git a/deps/icu-small/source/i18n/unicode/fpositer.h b/deps/icu-small/source/i18n/unicode/fpositer.h index 81091f0ffa..ba2a838315 100644 --- a/deps/icu-small/source/i18n/unicode/fpositer.h +++ b/deps/icu-small/source/i18n/unicode/fpositer.h @@ -19,6 +19,9 @@ #define FPOSITER_H #include "unicode/utypes.h" + +#if U_SHOW_CPLUSPLUS_API + #include "unicode/uobject.h" /** @@ -116,4 +119,6 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // FPOSITER_H diff --git a/deps/icu-small/source/i18n/unicode/gender.h b/deps/icu-small/source/i18n/unicode/gender.h index b7c31cb554..5ae111a3aa 100644 --- a/deps/icu-small/source/i18n/unicode/gender.h +++ b/deps/icu-small/source/i18n/unicode/gender.h @@ -25,6 +25,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING #include "unicode/locid.h" @@ -114,5 +116,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _GENDER //eof diff --git a/deps/icu-small/source/i18n/unicode/gregocal.h b/deps/icu-small/source/i18n/unicode/gregocal.h index 1d881e0be7..236bd003c1 100644 --- a/deps/icu-small/source/i18n/unicode/gregocal.h +++ b/deps/icu-small/source/i18n/unicode/gregocal.h @@ -28,6 +28,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING #include "unicode/calendar.h" @@ -301,7 +303,7 @@ public: * @return return a polymorphic copy of this calendar. * @stable ICU 2.0 */ - virtual Calendar* clone(void) const; + virtual GregorianCalendar* clone() const; /** * Sets the GregorianCalendar change date. This is the point when the switch from @@ -350,6 +352,7 @@ public: */ virtual UBool isEquivalentTo(const Calendar& other) const; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * (Overrides Calendar) Rolls up or down by the given amount in the specified field. * For more information, see the documentation for Calendar::roll(). @@ -362,6 +365,7 @@ public: * @deprecated ICU 2.6. Use roll(UCalendarDateFields field, int32_t amount, UErrorCode& status) instead. */ virtual void roll(EDateFields field, int32_t amount, UErrorCode& status); +#endif // U_FORCE_HIDE_DEPRECATED_API /** * (Overrides Calendar) Rolls up or down by the given amount in the specified field. @@ -774,5 +778,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _GREGOCAL //eof diff --git a/deps/icu-small/source/i18n/unicode/listformatter.h b/deps/icu-small/source/i18n/unicode/listformatter.h index 9ce8ec8617..88fc46cf37 100644 --- a/deps/icu-small/source/i18n/unicode/listformatter.h +++ b/deps/icu-small/source/i18n/unicode/listformatter.h @@ -21,6 +21,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #include "unicode/unistr.h" #include "unicode/locid.h" #include "unicode/formattedvalue.h" @@ -237,7 +239,7 @@ class U_I18N_API ListFormatter : public UObject{ UnicodeString& format(const UnicodeString items[], int32_t n_items, UnicodeString & appendTo, FieldPositionIterator* posIter, UErrorCode& errorCode) const; -#endif /* U_HIDE_DRAFT_API */ +#endif // U_HIDE_DRAFT_API #if !UCONFIG_NO_FORMATTING #ifndef U_HIDE_DRAFT_API @@ -298,4 +300,6 @@ class U_I18N_API ListFormatter : public UObject{ U_NAMESPACE_END +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // __LISTFORMATTER_H__ diff --git a/deps/icu-small/source/i18n/unicode/measfmt.h b/deps/icu-small/source/i18n/unicode/measfmt.h index d518665e14..8f73de87fa 100644 --- a/deps/icu-small/source/i18n/unicode/measfmt.h +++ b/deps/icu-small/source/i18n/unicode/measfmt.h @@ -15,6 +15,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING #include "unicode/format.h" @@ -151,7 +153,7 @@ class U_I18N_API MeasureFormat : public Format { * Clones this object polymorphically. * @stable ICU 53 */ - virtual Format *clone() const; + virtual MeasureFormat *clone() const; /** * Formats object to produce a string. @@ -163,6 +165,7 @@ class U_I18N_API MeasureFormat : public Format { FieldPosition &pos, UErrorCode &status) const; +#ifndef U_FORCE_HIDE_DRAFT_API /** * Parse a string to produce an object. This implementation sets * status to U_UNSUPPORTED_ERROR. @@ -173,6 +176,7 @@ class U_I18N_API MeasureFormat : public Format { const UnicodeString &source, Formattable &reslt, ParsePosition &pos) const; +#endif // U_FORCE_HIDE_DRAFT_API /** * Formats measure objects to produce a string. An example of such a @@ -382,17 +386,12 @@ class U_I18N_API MeasureFormat : public Format { int32_t bitMap, // 1=hour set, 2=minute set, 4=second set UnicodeString &appendTo, UErrorCode &status) const; - - UnicodeString &formatNumeric( - UDate date, - const DateFormat &dateFmt, - UDateFormatField smallestField, - const Formattable &smallestAmount, - UnicodeString &appendTo, - UErrorCode &status) const; }; U_NAMESPACE_END #endif // #if !UCONFIG_NO_FORMATTING + +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // #ifndef MEASUREFORMAT_H diff --git a/deps/icu-small/source/i18n/unicode/measunit.h b/deps/icu-small/source/i18n/unicode/measunit.h index d8e3c73956..08f337cb5b 100644 --- a/deps/icu-small/source/i18n/unicode/measunit.h +++ b/deps/icu-small/source/i18n/unicode/measunit.h @@ -15,6 +15,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING #include "unicode/unistr.h" @@ -62,7 +64,7 @@ class U_I18N_API MeasureUnit: public UObject { * have the same class as returned by getDynamicClassID(). * @stable ICU 3.0 */ - virtual UObject* clone() const; + virtual MeasureUnit* clone() const; /** * Destructor @@ -604,16 +606,14 @@ class U_I18N_API MeasureUnit: public UObject { static MeasureUnit getPartPerMillion(); #endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** * Returns by pointer, unit of concentr: percent. * Caller owns returned value and must free it. * Also see {@link #getPercent()}. * @param status ICU error code. - * @draft ICU 63 + * @stable ICU 63 */ static MeasureUnit *createPercent(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** @@ -624,16 +624,14 @@ class U_I18N_API MeasureUnit: public UObject { static MeasureUnit getPercent(); #endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** * Returns by pointer, unit of concentr: permille. * Caller owns returned value and must free it. * Also see {@link #getPermille()}. * @param status ICU error code. - * @draft ICU 63 + * @stable ICU 63 */ static MeasureUnit *createPermille(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** @@ -878,16 +876,14 @@ class U_I18N_API MeasureUnit: public UObject { static MeasureUnit getMegabyte(); #endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** * Returns by pointer, unit of digital: petabyte. * Caller owns returned value and must free it. * Also see {@link #getPetabyte()}. * @param status ICU error code. - * @draft ICU 63 + * @stable ICU 63 */ static MeasureUnit *createPetabyte(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** @@ -979,9 +975,7 @@ class U_I18N_API MeasureUnit: public UObject { * @draft ICU 64 */ static MeasureUnit *createDayPerson(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** * Returns by value, unit of duration: day-person. * Also see {@link #createDayPerson()}. @@ -990,6 +984,24 @@ class U_I18N_API MeasureUnit: public UObject { static MeasureUnit getDayPerson(); #endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of duration: decade. + * Caller owns returned value and must free it. + * Also see {@link #getDecade()}. + * @param status ICU error code. + * @draft ICU 65 + */ + static MeasureUnit *createDecade(UErrorCode &status); + + /** + * Returns by value, unit of duration: decade. + * Also see {@link #createDecade()}. + * @draft ICU 65 + */ + static MeasureUnit getDecade(); +#endif /* U_HIDE_DRAFT_API */ + /** * Returns by pointer, unit of duration: hour. * Caller owns returned value and must free it. @@ -1089,9 +1101,7 @@ class U_I18N_API MeasureUnit: public UObject { * @draft ICU 64 */ static MeasureUnit *createMonthPerson(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** * Returns by value, unit of duration: month-person. * Also see {@link #createMonthPerson()}. @@ -1163,9 +1173,7 @@ class U_I18N_API MeasureUnit: public UObject { * @draft ICU 64 */ static MeasureUnit *createWeekPerson(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** * Returns by value, unit of duration: week-person. * Also see {@link #createWeekPerson()}. @@ -1201,9 +1209,7 @@ class U_I18N_API MeasureUnit: public UObject { * @draft ICU 64 */ static MeasureUnit *createYearPerson(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** * Returns by value, unit of duration: year-person. * Also see {@link #createYearPerson()}. @@ -1430,6 +1436,24 @@ class U_I18N_API MeasureUnit: public UObject { #ifndef U_HIDE_DRAFT_API /** + * Returns by pointer, unit of energy: therm-us. + * Caller owns returned value and must free it. + * Also see {@link #getThermUs()}. + * @param status ICU error code. + * @draft ICU 65 + */ + static MeasureUnit *createThermUs(UErrorCode &status); + + /** + * Returns by value, unit of energy: therm-us. + * Also see {@link #createThermUs()}. + * @draft ICU 65 + */ + static MeasureUnit getThermUs(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** * Returns by pointer, unit of force: newton. * Caller owns returned value and must free it. * Also see {@link #getNewton()}. @@ -1536,6 +1560,132 @@ class U_I18N_API MeasureUnit: public UObject { static MeasureUnit getMegahertz(); #endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of graphics: dot-per-centimeter. + * Caller owns returned value and must free it. + * Also see {@link #getDotPerCentimeter()}. + * @param status ICU error code. + * @draft ICU 65 + */ + static MeasureUnit *createDotPerCentimeter(UErrorCode &status); + + /** + * Returns by value, unit of graphics: dot-per-centimeter. + * Also see {@link #createDotPerCentimeter()}. + * @draft ICU 65 + */ + static MeasureUnit getDotPerCentimeter(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of graphics: dot-per-inch. + * Caller owns returned value and must free it. + * Also see {@link #getDotPerInch()}. + * @param status ICU error code. + * @draft ICU 65 + */ + static MeasureUnit *createDotPerInch(UErrorCode &status); + + /** + * Returns by value, unit of graphics: dot-per-inch. + * Also see {@link #createDotPerInch()}. + * @draft ICU 65 + */ + static MeasureUnit getDotPerInch(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of graphics: em. + * Caller owns returned value and must free it. + * Also see {@link #getEm()}. + * @param status ICU error code. + * @draft ICU 65 + */ + static MeasureUnit *createEm(UErrorCode &status); + + /** + * Returns by value, unit of graphics: em. + * Also see {@link #createEm()}. + * @draft ICU 65 + */ + static MeasureUnit getEm(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of graphics: megapixel. + * Caller owns returned value and must free it. + * Also see {@link #getMegapixel()}. + * @param status ICU error code. + * @draft ICU 65 + */ + static MeasureUnit *createMegapixel(UErrorCode &status); + + /** + * Returns by value, unit of graphics: megapixel. + * Also see {@link #createMegapixel()}. + * @draft ICU 65 + */ + static MeasureUnit getMegapixel(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of graphics: pixel. + * Caller owns returned value and must free it. + * Also see {@link #getPixel()}. + * @param status ICU error code. + * @draft ICU 65 + */ + static MeasureUnit *createPixel(UErrorCode &status); + + /** + * Returns by value, unit of graphics: pixel. + * Also see {@link #createPixel()}. + * @draft ICU 65 + */ + static MeasureUnit getPixel(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of graphics: pixel-per-centimeter. + * Caller owns returned value and must free it. + * Also see {@link #getPixelPerCentimeter()}. + * @param status ICU error code. + * @draft ICU 65 + */ + static MeasureUnit *createPixelPerCentimeter(UErrorCode &status); + + /** + * Returns by value, unit of graphics: pixel-per-centimeter. + * Also see {@link #createPixelPerCentimeter()}. + * @draft ICU 65 + */ + static MeasureUnit getPixelPerCentimeter(); +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of graphics: pixel-per-inch. + * Caller owns returned value and must free it. + * Also see {@link #getPixelPerInch()}. + * @param status ICU error code. + * @draft ICU 65 + */ + static MeasureUnit *createPixelPerInch(UErrorCode &status); + + /** + * Returns by value, unit of graphics: pixel-per-inch. + * Also see {@link #createPixelPerInch()}. + * @draft ICU 65 + */ + static MeasureUnit getPixelPerInch(); +#endif /* U_HIDE_DRAFT_API */ + /** * Returns by pointer, unit of length: astronomical-unit. * Caller owns returned value and must free it. @@ -2310,16 +2460,14 @@ class U_I18N_API MeasureUnit: public UObject { static MeasureUnit getWatt(); #endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** * Returns by pointer, unit of pressure: atmosphere. * Caller owns returned value and must free it. * Also see {@link #getAtmosphere()}. * @param status ICU error code. - * @draft ICU 63 + * @stable ICU 63 */ static MeasureUnit *createAtmosphere(UErrorCode &status); -#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** @@ -2330,6 +2478,24 @@ class U_I18N_API MeasureUnit: public UObject { static MeasureUnit getAtmosphere(); #endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of pressure: bar. + * Caller owns returned value and must free it. + * Also see {@link #getBar()}. + * @param status ICU error code. + * @draft ICU 65 + */ + static MeasureUnit *createBar(UErrorCode &status); + + /** + * Returns by value, unit of pressure: bar. + * Also see {@link #createBar()}. + * @draft ICU 65 + */ + static MeasureUnit getBar(); +#endif /* U_HIDE_DRAFT_API */ + /** * Returns by pointer, unit of pressure: hectopascal. * Caller owns returned value and must free it. @@ -2438,6 +2604,24 @@ class U_I18N_API MeasureUnit: public UObject { static MeasureUnit getMillimeterOfMercury(); #endif /* U_HIDE_DRAFT_API */ +#ifndef U_HIDE_DRAFT_API + /** + * Returns by pointer, unit of pressure: pascal. + * Caller owns returned value and must free it. + * Also see {@link #getPascal()}. + * @param status ICU error code. + * @draft ICU 65 + */ + static MeasureUnit *createPascal(UErrorCode &status); + + /** + * Returns by value, unit of pressure: pascal. + * Also see {@link #createPascal()}. + * @draft ICU 65 + */ + static MeasureUnit getPascal(); +#endif /* U_HIDE_DRAFT_API */ + /** * Returns by pointer, unit of pressure: pound-per-square-inch. * Caller owns returned value and must free it. @@ -3164,4 +3348,7 @@ private: U_NAMESPACE_END #endif // !UNCONFIG_NO_FORMATTING + +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // __MEASUREUNIT_H__ diff --git a/deps/icu-small/source/i18n/unicode/measure.h b/deps/icu-small/source/i18n/unicode/measure.h index 71438d5c85..a15173d739 100644 --- a/deps/icu-small/source/i18n/unicode/measure.h +++ b/deps/icu-small/source/i18n/unicode/measure.h @@ -15,6 +15,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: MeasureUnit object. @@ -72,7 +74,7 @@ class U_I18N_API Measure: public UObject { * have the same class as returned by getDynamicClassID(). * @stable ICU 3.0 */ - virtual UObject* clone() const; + virtual Measure* clone() const; /** * Destructor @@ -158,4 +160,7 @@ inline const MeasureUnit& Measure::getUnit() const { U_NAMESPACE_END #endif // !UCONFIG_NO_FORMATTING + +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // __MEASURE_H__ diff --git a/deps/icu-small/source/i18n/unicode/msgfmt.h b/deps/icu-small/source/i18n/unicode/msgfmt.h index 8e1bf9b45f..99b0eaeec1 100644 --- a/deps/icu-small/source/i18n/unicode/msgfmt.h +++ b/deps/icu-small/source/i18n/unicode/msgfmt.h @@ -21,6 +21,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Formats messages in a language-neutral way. @@ -184,7 +186,7 @@ class NumberFormat; * <td><i>argSkeletonText</i> * <td><code>NumberFormatter::forSkeleton(argSkeletonText, status).locale(getLocale()).toFormat(status)</code> * <tr> - * <td rowspan=6><code>date</code> + * <td rowspan=7><code>date</code> * <td><i>(none)</i> * <td><code>DateFormat.createDateInstance(kDefault, getLocale(), status)</code> * <tr> @@ -418,7 +420,7 @@ public: * result and should delete it when done. * @stable ICU 2.0 */ - virtual Format* clone(void) const; + virtual MessageFormat* clone() const; /** * Returns true if the given Format objects are semantically equal. @@ -1087,7 +1089,7 @@ private: class U_I18N_API DummyFormat : public Format { public: virtual UBool operator==(const Format&) const; - virtual Format* clone() const; + virtual DummyFormat* clone() const; virtual UnicodeString& format(const Formattable& obj, UnicodeString& appendTo, UErrorCode& status) const; @@ -1111,5 +1113,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _MSGFMT //eof diff --git a/deps/icu-small/source/i18n/unicode/nounit.h b/deps/icu-small/source/i18n/unicode/nounit.h index 879849b16b..61b5c16ee3 100644 --- a/deps/icu-small/source/i18n/unicode/nounit.h +++ b/deps/icu-small/source/i18n/unicode/nounit.h @@ -12,11 +12,14 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING -#ifndef U_HIDE_DRAFT_API #include "unicode/measunit.h" +#ifndef U_HIDE_DRAFT_API + /** * \file * \brief C++ API: units for percent and permille @@ -72,7 +75,7 @@ public: * have the same class as returned by getDynamicClassID(). * @draft ICU 60 */ - virtual UObject* clone() const; + virtual NoUnit* clone() const; /** * Returns a unique class ID for this object POLYMORPHICALLY. @@ -106,6 +109,8 @@ U_NAMESPACE_END #endif /* U_HIDE_DRAFT_API */ #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // __NOUNIT_H__ //eof // diff --git a/deps/icu-small/source/i18n/unicode/numberformatter.h b/deps/icu-small/source/i18n/unicode/numberformatter.h index e9fe39a931..6d48f18ab5 100644 --- a/deps/icu-small/source/i18n/unicode/numberformatter.h +++ b/deps/icu-small/source/i18n/unicode/numberformatter.h @@ -1,15 +1,19 @@ // © 2017 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html +#ifndef __NUMBERFORMATTER_H__ +#define __NUMBERFORMATTER_H__ + #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING -#ifndef __NUMBERFORMATTER_H__ -#define __NUMBERFORMATTER_H__ #include "unicode/appendable.h" -#include "unicode/dcfmtsym.h" +#include "unicode/bytestream.h" #include "unicode/currunit.h" +#include "unicode/dcfmtsym.h" #include "unicode/fieldpos.h" #include "unicode/formattedvalue.h" #include "unicode/fpositer.h" @@ -22,8 +26,6 @@ #include "unicode/unumberformatter.h" #include "unicode/uobject.h" -#ifndef U_HIDE_DRAFT_API - /** * \file * \brief C++ API: Library for localized number formatting introduced in ICU 60. @@ -85,6 +87,7 @@ U_NAMESPACE_BEGIN // Forward declarations: class IFixedDecimal; class FieldPositionIteratorHandler; +class FormattedStringBuilder; namespace numparse { namespace impl { @@ -142,7 +145,6 @@ class MultiplierProducer; class RoundingImpl; class ScientificHandler; class Modifier; -class NumberStringBuilder; class AffixPatternProvider; class NumberPropertyMapper; struct DecimalFormatProperties; @@ -167,21 +169,21 @@ void touchRangeLocales(impl::RangeMacroProps& macros); /** * Extra name reserved in case it is needed in the future. * - * @draft ICU 63 + * @stable ICU 63 */ typedef Notation CompactNotation; /** * Extra name reserved in case it is needed in the future. * - * @draft ICU 63 + * @stable ICU 63 */ typedef Notation SimpleNotation; /** * A class that defines the notation style to be used when formatting numbers in NumberFormatter. * - * @draft ICU 60 + * @stable ICU 60 */ class U_I18N_API Notation : public UMemory { public: @@ -207,7 +209,7 @@ class U_I18N_API Notation : public UMemory { * </pre> * * @return A ScientificNotation for chaining or passing to the NumberFormatter notation() setter. - * @draft ICU 60 + * @stable ICU 60 */ static ScientificNotation scientific(); @@ -231,7 +233,7 @@ class U_I18N_API Notation : public UMemory { * </pre> * * @return A ScientificNotation for chaining or passing to the NumberFormatter notation() setter. - * @draft ICU 60 + * @stable ICU 60 */ static ScientificNotation engineering(); @@ -274,7 +276,7 @@ class U_I18N_API Notation : public UMemory { * </pre> * * @return A CompactNotation for passing to the NumberFormatter notation() setter. - * @draft ICU 60 + * @stable ICU 60 */ static CompactNotation compactShort(); @@ -298,7 +300,7 @@ class U_I18N_API Notation : public UMemory { * </pre> * * @return A CompactNotation for passing to the NumberFormatter notation() setter. - * @draft ICU 60 + * @stable ICU 60 */ static CompactNotation compactLong(); @@ -324,7 +326,7 @@ class U_I18N_API Notation : public UMemory { * </pre> * * @return A SimpleNotation for passing to the NumberFormatter notation() setter. - * @draft ICU 60 + * @stable ICU 60 */ static SimpleNotation simple(); @@ -391,7 +393,7 @@ class U_I18N_API Notation : public UMemory { * <p> * To create a ScientificNotation, use one of the factory methods in {@link Notation}. * - * @draft ICU 60 + * @stable ICU 60 */ class U_I18N_API ScientificNotation : public Notation { public: @@ -406,7 +408,7 @@ class U_I18N_API ScientificNotation : public Notation { * @param minExponentDigits * The minimum number of digits to show in the exponent. * @return A ScientificNotation, for chaining. - * @draft ICU 60 + * @stable ICU 60 */ ScientificNotation withMinExponentDigits(int32_t minExponentDigits) const; @@ -421,7 +423,7 @@ class U_I18N_API ScientificNotation : public Notation { * @param exponentSignDisplay * The strategy for displaying the sign in the exponent. * @return A ScientificNotation, for chaining. - * @draft ICU 60 + * @stable ICU 60 */ ScientificNotation withExponentSignDisplay(UNumberSignDisplay exponentSignDisplay) const; @@ -442,7 +444,7 @@ class U_I18N_API ScientificNotation : public Notation { /** * Extra name reserved in case it is needed in the future. * - * @draft ICU 63 + * @stable ICU 63 */ typedef Precision SignificantDigitsPrecision; @@ -452,7 +454,7 @@ typedef Precision SignificantDigitsPrecision; * <p> * To create a Precision, use one of the factory methods. * - * @draft ICU 60 + * @stable ICU 60 */ class U_I18N_API Precision : public UMemory { @@ -472,7 +474,7 @@ class U_I18N_API Precision : public UMemory { * http://www.serpentine.com/blog/2011/06/29/here-be-dragons-advances-in-problems-you-didnt-even-know-you-had/ * * @return A Precision for chaining or passing to the NumberFormatter precision() setter. - * @draft ICU 60 + * @stable ICU 60 */ static Precision unlimited(); @@ -480,7 +482,7 @@ class U_I18N_API Precision : public UMemory { * Show numbers rounded if necessary to the nearest integer. * * @return A FractionPrecision for chaining or passing to the NumberFormatter precision() setter. - * @draft ICU 60 + * @stable ICU 60 */ static FractionPrecision integer(); @@ -509,7 +511,7 @@ class U_I18N_API Precision : public UMemory { * The minimum and maximum number of numerals to display after the decimal separator (rounding if too * long or padding with zeros if too short). * @return A FractionPrecision for chaining or passing to the NumberFormatter precision() setter. - * @draft ICU 60 + * @stable ICU 60 */ static FractionPrecision fixedFraction(int32_t minMaxFractionPlaces); @@ -524,7 +526,7 @@ class U_I18N_API Precision : public UMemory { * The minimum number of numerals to display after the decimal separator (padding with zeros if * necessary). * @return A FractionPrecision for chaining or passing to the NumberFormatter precision() setter. - * @draft ICU 60 + * @stable ICU 60 */ static FractionPrecision minFraction(int32_t minFractionPlaces); @@ -536,7 +538,7 @@ class U_I18N_API Precision : public UMemory { * @param maxFractionPlaces * The maximum number of numerals to display after the decimal mark (rounding if necessary). * @return A FractionPrecision for chaining or passing to the NumberFormatter precision() setter. - * @draft ICU 60 + * @stable ICU 60 */ static FractionPrecision maxFraction(int32_t maxFractionPlaces); @@ -551,7 +553,7 @@ class U_I18N_API Precision : public UMemory { * @param maxFractionPlaces * The maximum number of numerals to display after the decimal separator (rounding if necessary). * @return A FractionPrecision for chaining or passing to the NumberFormatter precision() setter. - * @draft ICU 60 + * @stable ICU 60 */ static FractionPrecision minMaxFraction(int32_t minFractionPlaces, int32_t maxFractionPlaces); @@ -566,7 +568,7 @@ class U_I18N_API Precision : public UMemory { * The minimum and maximum number of significant digits to display (rounding if too long or padding with * zeros if too short). * @return A precision for chaining or passing to the NumberFormatter precision() setter. - * @draft ICU 62 + * @stable ICU 62 */ static SignificantDigitsPrecision fixedSignificantDigits(int32_t minMaxSignificantDigits); @@ -580,7 +582,7 @@ class U_I18N_API Precision : public UMemory { * @param minSignificantDigits * The minimum number of significant digits to display (padding with zeros if too short). * @return A precision for chaining or passing to the NumberFormatter precision() setter. - * @draft ICU 62 + * @stable ICU 62 */ static SignificantDigitsPrecision minSignificantDigits(int32_t minSignificantDigits); @@ -590,7 +592,7 @@ class U_I18N_API Precision : public UMemory { * @param maxSignificantDigits * The maximum number of significant digits to display (rounding if too long). * @return A precision for chaining or passing to the NumberFormatter precision() setter. - * @draft ICU 62 + * @stable ICU 62 */ static SignificantDigitsPrecision maxSignificantDigits(int32_t maxSignificantDigits); @@ -603,7 +605,7 @@ class U_I18N_API Precision : public UMemory { * @param maxSignificantDigits * The maximum number of significant digits to display (rounding if necessary). * @return A precision for chaining or passing to the NumberFormatter precision() setter. - * @draft ICU 62 + * @stable ICU 62 */ static SignificantDigitsPrecision minMaxSignificantDigits(int32_t minSignificantDigits, int32_t maxSignificantDigits); @@ -625,7 +627,7 @@ class U_I18N_API Precision : public UMemory { * @param roundingIncrement * The increment to which to round numbers. * @return A precision for chaining or passing to the NumberFormatter precision() setter. - * @draft ICU 60 + * @stable ICU 60 */ static IncrementPrecision increment(double roundingIncrement); @@ -644,7 +646,7 @@ class U_I18N_API Precision : public UMemory { * Either STANDARD (for digital transactions) or CASH (for transactions where the rounding increment may * be limited by the available denominations of cash or coins). * @return A CurrencyPrecision for chaining or passing to the NumberFormatter precision() setter. - * @draft ICU 60 + * @stable ICU 60 */ static CurrencyPrecision currency(UCurrencyUsage currencyUsage); @@ -771,7 +773,7 @@ class U_I18N_API Precision : public UMemory { * <p> * To create a FractionPrecision, use one of the factory methods on Precision. * - * @draft ICU 60 + * @stable ICU 60 */ class U_I18N_API FractionPrecision : public Precision { public: @@ -789,7 +791,7 @@ class U_I18N_API FractionPrecision : public Precision { * @param minSignificantDigits * The number of significant figures to guarantee. * @return A precision for chaining or passing to the NumberFormatter precision() setter. - * @draft ICU 60 + * @stable ICU 60 */ Precision withMinDigits(int32_t minSignificantDigits) const; @@ -808,7 +810,7 @@ class U_I18N_API FractionPrecision : public Precision { * @param maxSignificantDigits * Round the number to no more than this number of significant figures. * @return A precision for chaining or passing to the NumberFormatter precision() setter. - * @draft ICU 60 + * @stable ICU 60 */ Precision withMaxDigits(int32_t maxSignificantDigits) const; @@ -827,7 +829,7 @@ class U_I18N_API FractionPrecision : public Precision { * <p> * To create a CurrencyPrecision, use one of the factory methods on Precision. * - * @draft ICU 60 + * @stable ICU 60 */ class U_I18N_API CurrencyPrecision : public Precision { public: @@ -846,7 +848,7 @@ class U_I18N_API CurrencyPrecision : public Precision { * @param currency * The currency to associate with this rounding precision. * @return A precision for chaining or passing to the NumberFormatter precision() setter. - * @draft ICU 60 + * @stable ICU 60 */ Precision withCurrency(const CurrencyUnit ¤cy) const; @@ -865,7 +867,7 @@ class U_I18N_API CurrencyPrecision : public Precision { * <p> * To create an IncrementPrecision, use one of the factory methods on Precision. * - * @draft ICU 60 + * @stable ICU 60 */ class U_I18N_API IncrementPrecision : public Precision { public: @@ -882,7 +884,7 @@ class U_I18N_API IncrementPrecision : public Precision { * * @param minFrac The minimum number of digits after the decimal separator. * @return A precision for chaining or passing to the NumberFormatter precision() setter. - * @draft ICU 60 + * @stable ICU 60 */ Precision withMinFraction(int32_t minFrac) const; @@ -900,7 +902,7 @@ class U_I18N_API IncrementPrecision : public Precision { * <p> * To create an IntegerWidth, use one of the factory methods. * - * @draft ICU 60 + * @stable ICU 60 * @see NumberFormatter */ class U_I18N_API IntegerWidth : public UMemory { @@ -914,7 +916,7 @@ class U_I18N_API IntegerWidth : public UMemory { * @param minInt * The minimum number of places before the decimal separator. * @return An IntegerWidth for chaining or passing to the NumberFormatter integerWidth() setter. - * @draft ICU 60 + * @stable ICU 60 */ static IntegerWidth zeroFillTo(int32_t minInt); @@ -927,7 +929,7 @@ class U_I18N_API IntegerWidth : public UMemory { * The maximum number of places before the decimal separator. maxInt == -1 means no * truncation. * @return An IntegerWidth for passing to the NumberFormatter integerWidth() setter. - * @draft ICU 60 + * @stable ICU 60 */ IntegerWidth truncateAt(int32_t maxInt); @@ -994,7 +996,7 @@ class U_I18N_API IntegerWidth : public UMemory { * <p> * To create a Scale, use one of the factory methods. * - * @draft ICU 62 + * @stable ICU 62 */ class U_I18N_API Scale : public UMemory { public: @@ -1002,7 +1004,7 @@ class U_I18N_API Scale : public UMemory { * Do not change the value of numbers when formatting or parsing. * * @return A Scale to prevent any multiplication. - * @draft ICU 62 + * @stable ICU 62 */ static Scale none(); @@ -1014,7 +1016,7 @@ class U_I18N_API Scale : public UMemory { * </pre> * * @return A Scale for passing to the setter in NumberFormatter. - * @draft ICU 62 + * @stable ICU 62 */ static Scale powerOfTen(int32_t power); @@ -1028,7 +1030,7 @@ class U_I18N_API Scale : public UMemory { * Also see the version of this method that takes a double. * * @return A Scale for passing to the setter in NumberFormatter. - * @draft ICU 62 + * @stable ICU 62 */ static Scale byDecimal(StringPiece multiplicand); @@ -1038,7 +1040,7 @@ class U_I18N_API Scale : public UMemory { * This method takes a double; also see the version of this method that takes an exact decimal. * * @return A Scale for passing to the setter in NumberFormatter. - * @draft ICU 62 + * @stable ICU 62 */ static Scale byDouble(double multiplicand); @@ -1046,26 +1048,26 @@ class U_I18N_API Scale : public UMemory { * Multiply a number by both a power of ten and by an arbitrary double value. * * @return A Scale for passing to the setter in NumberFormatter. - * @draft ICU 62 + * @stable ICU 62 */ static Scale byDoubleAndPowerOfTen(double multiplicand, int32_t power); // We need a custom destructor for the DecNum, which means we need to declare // the copy/move constructor/assignment quartet. - /** @draft ICU 62 */ + /** @stable ICU 62 */ Scale(const Scale& other); - /** @draft ICU 62 */ + /** @stable ICU 62 */ Scale& operator=(const Scale& other); - /** @draft ICU 62 */ + /** @stable ICU 62 */ Scale(Scale&& src) U_NOEXCEPT; - /** @draft ICU 62 */ + /** @stable ICU 62 */ Scale& operator=(Scale&& src) U_NOEXCEPT; - /** @draft ICU 62 */ + /** @stable ICU 62 */ ~Scale(); #ifndef U_HIDE_INTERNAL_API @@ -1343,7 +1345,7 @@ class U_I18N_API Padder : public UMemory { } int32_t padAndApply(const impl::Modifier &mod1, const impl::Modifier &mod2, - impl::NumberStringBuilder &string, int32_t leftIndex, int32_t rightIndex, + FormattedStringBuilder &string, int32_t leftIndex, int32_t rightIndex, UErrorCode &status) const; // To allow MacroProps/MicroProps to initialize empty instances: @@ -1465,7 +1467,7 @@ class U_I18N_API NumberFormatterSettings { * The notation strategy to use. * @return The fluent chain. * @see Notation - * @draft ICU 60 + * @stable ICU 60 */ Derived notation(const Notation ¬ation) const &; @@ -1476,7 +1478,7 @@ class U_I18N_API NumberFormatterSettings { * The notation strategy to use. * @return The fluent chain. * @see #notation - * @draft ICU 62 + * @stable ICU 62 */ Derived notation(const Notation ¬ation) &&; @@ -1521,7 +1523,7 @@ class U_I18N_API NumberFormatterSettings { * @see Currency * @see NoUnit * @see #perUnit - * @draft ICU 60 + * @stable ICU 60 */ Derived unit(const icu::MeasureUnit &unit) const &; @@ -1532,7 +1534,7 @@ class U_I18N_API NumberFormatterSettings { * The unit to render. * @return The fluent chain. * @see #unit - * @draft ICU 62 + * @stable ICU 62 */ Derived unit(const icu::MeasureUnit &unit) &&; @@ -1547,7 +1549,7 @@ class U_I18N_API NumberFormatterSettings { * @return The fluent chain. * @see #unit * @see MeasureUnit - * @draft ICU 60 + * @stable ICU 60 */ Derived adoptUnit(icu::MeasureUnit *unit) const &; @@ -1558,7 +1560,7 @@ class U_I18N_API NumberFormatterSettings { * The unit to render. * @return The fluent chain. * @see #adoptUnit - * @draft ICU 62 + * @stable ICU 62 */ Derived adoptUnit(icu::MeasureUnit *unit) &&; @@ -1582,7 +1584,7 @@ class U_I18N_API NumberFormatterSettings { * The unit to render in the denominator. * @return The fluent chain * @see #unit - * @draft ICU 61 + * @stable ICU 61 */ Derived perUnit(const icu::MeasureUnit &perUnit) const &; @@ -1593,7 +1595,7 @@ class U_I18N_API NumberFormatterSettings { * The unit to render in the denominator. * @return The fluent chain. * @see #perUnit - * @draft ICU 62 + * @stable ICU 62 */ Derived perUnit(const icu::MeasureUnit &perUnit) &&; @@ -1608,7 +1610,7 @@ class U_I18N_API NumberFormatterSettings { * @return The fluent chain. * @see #perUnit * @see MeasureUnit - * @draft ICU 61 + * @stable ICU 61 */ Derived adoptPerUnit(icu::MeasureUnit *perUnit) const &; @@ -1619,7 +1621,7 @@ class U_I18N_API NumberFormatterSettings { * The unit to render in the denominator. * @return The fluent chain. * @see #adoptPerUnit - * @draft ICU 62 + * @stable ICU 62 */ Derived adoptPerUnit(icu::MeasureUnit *perUnit) &&; @@ -1651,7 +1653,7 @@ class U_I18N_API NumberFormatterSettings { * The rounding precision to use. * @return The fluent chain. * @see Precision - * @draft ICU 62 + * @stable ICU 62 */ Derived precision(const Precision& precision) const &; @@ -1662,7 +1664,7 @@ class U_I18N_API NumberFormatterSettings { * The rounding precision to use. * @return The fluent chain. * @see #precision - * @draft ICU 62 + * @stable ICU 62 */ Derived precision(const Precision& precision) &&; @@ -1682,7 +1684,7 @@ class U_I18N_API NumberFormatterSettings { * * @param roundingMode The rounding mode to use. * @return The fluent chain. - * @draft ICU 62 + * @stable ICU 62 */ Derived roundingMode(UNumberFormatRoundingMode roundingMode) const &; @@ -1692,7 +1694,7 @@ class U_I18N_API NumberFormatterSettings { * @param roundingMode The rounding mode to use. * @return The fluent chain. * @see #roundingMode - * @draft ICU 62 + * @stable ICU 62 */ Derived roundingMode(UNumberFormatRoundingMode roundingMode) &&; @@ -1721,7 +1723,7 @@ class U_I18N_API NumberFormatterSettings { * @param strategy * The grouping strategy to use. * @return The fluent chain. - * @draft ICU 61 + * @stable ICU 61 */ Derived grouping(UNumberGroupingStrategy strategy) const &; @@ -1732,7 +1734,7 @@ class U_I18N_API NumberFormatterSettings { * The grouping strategy to use. * @return The fluent chain. * @see #grouping - * @draft ICU 62 + * @stable ICU 62 */ Derived grouping(UNumberGroupingStrategy strategy) &&; @@ -1758,7 +1760,7 @@ class U_I18N_API NumberFormatterSettings { * The integer width to use. * @return The fluent chain. * @see IntegerWidth - * @draft ICU 60 + * @stable ICU 60 */ Derived integerWidth(const IntegerWidth &style) const &; @@ -1769,7 +1771,7 @@ class U_I18N_API NumberFormatterSettings { * The integer width to use. * @return The fluent chain. * @see #integerWidth - * @draft ICU 62 + * @stable ICU 62 */ Derived integerWidth(const IntegerWidth &style) &&; @@ -1811,7 +1813,7 @@ class U_I18N_API NumberFormatterSettings { * The DecimalFormatSymbols to use. * @return The fluent chain. * @see DecimalFormatSymbols - * @draft ICU 60 + * @stable ICU 60 */ Derived symbols(const DecimalFormatSymbols &symbols) const &; @@ -1822,7 +1824,7 @@ class U_I18N_API NumberFormatterSettings { * The DecimalFormatSymbols to use. * @return The fluent chain. * @see #symbols - * @draft ICU 62 + * @stable ICU 62 */ Derived symbols(const DecimalFormatSymbols &symbols) &&; @@ -1857,7 +1859,7 @@ class U_I18N_API NumberFormatterSettings { * The NumberingSystem to use. * @return The fluent chain. * @see NumberingSystem - * @draft ICU 60 + * @stable ICU 60 */ Derived adoptSymbols(NumberingSystem *symbols) const &; @@ -1868,7 +1870,7 @@ class U_I18N_API NumberFormatterSettings { * The NumberingSystem to use. * @return The fluent chain. * @see #adoptSymbols - * @draft ICU 62 + * @stable ICU 62 */ Derived adoptSymbols(NumberingSystem *symbols) &&; @@ -1895,7 +1897,7 @@ class U_I18N_API NumberFormatterSettings { * The width to use when rendering numbers. * @return The fluent chain * @see UNumberUnitWidth - * @draft ICU 60 + * @stable ICU 60 */ Derived unitWidth(UNumberUnitWidth width) const &; @@ -1906,7 +1908,7 @@ class U_I18N_API NumberFormatterSettings { * The width to use when rendering numbers. * @return The fluent chain. * @see #unitWidth - * @draft ICU 62 + * @stable ICU 62 */ Derived unitWidth(UNumberUnitWidth width) &&; @@ -1933,7 +1935,7 @@ class U_I18N_API NumberFormatterSettings { * The sign display strategy to use when rendering numbers. * @return The fluent chain * @see UNumberSignDisplay - * @draft ICU 60 + * @stable ICU 60 */ Derived sign(UNumberSignDisplay style) const &; @@ -1944,7 +1946,7 @@ class U_I18N_API NumberFormatterSettings { * The sign display strategy to use when rendering numbers. * @return The fluent chain. * @see #sign - * @draft ICU 62 + * @stable ICU 62 */ Derived sign(UNumberSignDisplay style) &&; @@ -1971,7 +1973,7 @@ class U_I18N_API NumberFormatterSettings { * The decimal separator display strategy to use when rendering numbers. * @return The fluent chain * @see UNumberDecimalSeparatorDisplay - * @draft ICU 60 + * @stable ICU 60 */ Derived decimal(UNumberDecimalSeparatorDisplay style) const &; @@ -1982,7 +1984,7 @@ class U_I18N_API NumberFormatterSettings { * The decimal separator display strategy to use when rendering numbers. * @return The fluent chain. * @see #decimal - * @draft ICU 62 + * @stable ICU 62 */ Derived decimal(UNumberDecimalSeparatorDisplay style) &&; @@ -2008,7 +2010,7 @@ class U_I18N_API NumberFormatterSettings { * @param scale * The scale to apply when rendering numbers. * @return The fluent chain - * @draft ICU 62 + * @stable ICU 62 */ Derived scale(const Scale &scale) const &; @@ -2019,7 +2021,7 @@ class U_I18N_API NumberFormatterSettings { * The scale to apply when rendering numbers. * @return The fluent chain. * @see #scale - * @draft ICU 62 + * @stable ICU 62 */ Derived scale(const Scale &scale) &&; @@ -2076,10 +2078,11 @@ class U_I18N_API NumberFormatterSettings { * behavior should produce the same skeleton. * * @return A number skeleton string with behavior corresponding to this number formatter. - * @draft ICU 62 + * @stable ICU 62 */ UnicodeString toSkeleton(UErrorCode& status) const; +#ifndef U_HIDE_DRAFT_API /** * Returns the current (Un)LocalizedNumberFormatter as a LocalPointer * wrapping a heap-allocated copy of the current object. @@ -2101,12 +2104,13 @@ class U_I18N_API NumberFormatterSettings { * @draft ICU 64 */ LocalPointer<Derived> clone() &&; +#endif /* U_HIDE_DRAFT_API */ /** * Sets the UErrorCode if an error occurred in the fluent chain. * Preserves older error codes in the outErrorCode. * @return TRUE if U_FAILURE(outErrorCode) - * @draft ICU 60 + * @stable ICU 60 */ UBool copyErrorTo(UErrorCode &outErrorCode) const { if (U_FAILURE(outErrorCode)) { @@ -2139,7 +2143,7 @@ class U_I18N_API NumberFormatterSettings { * Instances of this class are immutable and thread-safe. * * @see NumberFormatter - * @draft ICU 60 + * @stable ICU 60 */ class U_I18N_API UnlocalizedNumberFormatter : public NumberFormatterSettings<UnlocalizedNumberFormatter>, public UMemory { @@ -2152,7 +2156,7 @@ class U_I18N_API UnlocalizedNumberFormatter * @param locale * The locale to use when loading data for number formatting. * @return The fluent chain. - * @draft ICU 60 + * @stable ICU 60 */ LocalizedNumberFormatter locale(const icu::Locale &locale) const &; @@ -2163,40 +2167,40 @@ class U_I18N_API UnlocalizedNumberFormatter * The locale to use when loading data for number formatting. * @return The fluent chain. * @see #locale - * @draft ICU 62 + * @stable ICU 62 */ LocalizedNumberFormatter locale(const icu::Locale &locale) &&; /** * Default constructor: puts the formatter into a valid but undefined state. * - * @draft ICU 62 + * @stable ICU 62 */ UnlocalizedNumberFormatter() = default; /** * Returns a copy of this UnlocalizedNumberFormatter. - * @draft ICU 60 + * @stable ICU 60 */ UnlocalizedNumberFormatter(const UnlocalizedNumberFormatter &other); /** * Move constructor: * The source UnlocalizedNumberFormatter will be left in a valid but undefined state. - * @draft ICU 62 + * @stable ICU 62 */ UnlocalizedNumberFormatter(UnlocalizedNumberFormatter&& src) U_NOEXCEPT; /** * Copy assignment operator. - * @draft ICU 62 + * @stable ICU 62 */ UnlocalizedNumberFormatter& operator=(const UnlocalizedNumberFormatter& other); /** * Move assignment operator: * The source UnlocalizedNumberFormatter will be left in a valid but undefined state. - * @draft ICU 62 + * @stable ICU 62 */ UnlocalizedNumberFormatter& operator=(UnlocalizedNumberFormatter&& src) U_NOEXCEPT; @@ -2219,7 +2223,7 @@ class U_I18N_API UnlocalizedNumberFormatter * Instances of this class are immutable and thread-safe. * * @see NumberFormatter - * @draft ICU 60 + * @stable ICU 60 */ class U_I18N_API LocalizedNumberFormatter : public NumberFormatterSettings<LocalizedNumberFormatter>, public UMemory { @@ -2233,7 +2237,7 @@ class U_I18N_API LocalizedNumberFormatter * @param status * Set to an ErrorCode if one occurred in the setter chain or during formatting. * @return A FormattedNumber object; call .toString() to get the string. - * @draft ICU 60 + * @stable ICU 60 */ FormattedNumber formatInt(int64_t value, UErrorCode &status) const; @@ -2246,7 +2250,7 @@ class U_I18N_API LocalizedNumberFormatter * @param status * Set to an ErrorCode if one occurred in the setter chain or during formatting. * @return A FormattedNumber object; call .toString() to get the string. - * @draft ICU 60 + * @stable ICU 60 */ FormattedNumber formatDouble(double value, UErrorCode &status) const; @@ -2262,7 +2266,7 @@ class U_I18N_API LocalizedNumberFormatter * @param status * Set to an ErrorCode if one occurred in the setter chain or during formatting. * @return A FormattedNumber object; call .toString() to get the string. - * @draft ICU 60 + * @stable ICU 60 */ FormattedNumber formatDecimal(StringPiece value, UErrorCode& status) const; @@ -2303,40 +2307,40 @@ class U_I18N_API LocalizedNumberFormatter * The caller owns the returned object and must delete it when finished. * * @return A Format wrapping this LocalizedNumberFormatter. - * @draft ICU 62 + * @stable ICU 62 */ Format* toFormat(UErrorCode& status) const; /** * Default constructor: puts the formatter into a valid but undefined state. * - * @draft ICU 62 + * @stable ICU 62 */ LocalizedNumberFormatter() = default; /** * Returns a copy of this LocalizedNumberFormatter. - * @draft ICU 60 + * @stable ICU 60 */ LocalizedNumberFormatter(const LocalizedNumberFormatter &other); /** * Move constructor: * The source LocalizedNumberFormatter will be left in a valid but undefined state. - * @draft ICU 62 + * @stable ICU 62 */ LocalizedNumberFormatter(LocalizedNumberFormatter&& src) U_NOEXCEPT; /** * Copy assignment operator. - * @draft ICU 62 + * @stable ICU 62 */ LocalizedNumberFormatter& operator=(const LocalizedNumberFormatter& other); /** * Move assignment operator: * The source LocalizedNumberFormatter will be left in a valid but undefined state. - * @draft ICU 62 + * @stable ICU 62 */ LocalizedNumberFormatter& operator=(LocalizedNumberFormatter&& src) U_NOEXCEPT; @@ -2360,7 +2364,7 @@ class U_I18N_API LocalizedNumberFormatter /** * Destruct this LocalizedNumberFormatter, cleaning up any memory it might own. - * @draft ICU 60 + * @stable ICU 60 */ ~LocalizedNumberFormatter(); @@ -2401,27 +2405,30 @@ class U_I18N_API LocalizedNumberFormatter * * Instances of this class are immutable and thread-safe. * - * @draft ICU 60 + * @stable ICU 60 */ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue { public: + // Default constructor cannot have #ifndef U_HIDE_DRAFT_API +#ifndef U_FORCE_HIDE_DRAFT_API /** * Default constructor; makes an empty FormattedNumber. * @draft ICU 64 */ FormattedNumber() : fData(nullptr), fErrorCode(U_INVALID_STATE_ERROR) {} +#endif // U_FORCE_HIDE_DRAFT_API /** * Move constructor: Leaves the source FormattedNumber in an undefined state. - * @draft ICU 62 + * @stable ICU 62 */ FormattedNumber(FormattedNumber&& src) U_NOEXCEPT; /** * Destruct an instance of FormattedNumber. - * @draft ICU 60 + * @stable ICU 60 */ virtual ~FormattedNumber() U_OVERRIDE; @@ -2433,7 +2440,7 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue { /** * Move assignment: Leaves the source FormattedNumber in an undefined state. - * @draft ICU 62 + * @stable ICU 62 */ FormattedNumber& operator=(FormattedNumber&& src) U_NOEXCEPT; @@ -2443,7 +2450,7 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue { * * For more information, see FormattedValue::toString() * - * @draft ICU 62 + * @stable ICU 62 */ UnicodeString toString(UErrorCode& status) const U_OVERRIDE; @@ -2457,7 +2464,7 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue { * * For more information, see FormattedValue::appendTo() * - * @draft ICU 62 + * @stable ICU 62 */ Appendable &appendTo(Appendable& appendable, UErrorCode& status) const U_OVERRIDE; @@ -2465,6 +2472,7 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue { /** @copydoc FormattedValue::nextPosition() */ UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE; +#ifndef U_HIDE_DRAFT_API /** * Determines the start (inclusive) and end (exclusive) indices of the next occurrence of the given * <em>field</em> in the output string. This allows you to determine the locations of, for example, @@ -2516,6 +2524,30 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue { * @see UNumberFormatFields */ void getAllFieldPositions(FieldPositionIterator &iterator, UErrorCode &status) const; +#endif /* U_HIDE_DRAFT_API */ + +#ifndef U_HIDE_DRAFT_API + /** + * Export the formatted number as a "numeric string" conforming to the + * syntax defined in the Decimal Arithmetic Specification, available at + * http://speleotrove.com/decimal + * + * This endpoint is useful for obtaining the exact number being printed + * after scaling and rounding have been applied by the number formatter. + * + * Example call site: + * + * auto decimalNumber = fn.toDecimalNumber<std::string>(status); + * + * @tparam StringClass A string class compatible with StringByteSink; + * for example, std::string. + * @param status Set if an error occurs. + * @return A StringClass containing the numeric string. + * @draft ICU 65 + */ + template<typename StringClass> + inline StringClass toDecimalNumber(UErrorCode& status) const; +#endif // U_HIDE_DRAFT_API #ifndef U_HIDE_INTERNAL_API @@ -2550,6 +2582,9 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue { explicit FormattedNumber(UErrorCode errorCode) : fData(nullptr), fErrorCode(errorCode) {} + // TODO(ICU-20775): Propose this as API. + void toDecimalNumber(ByteSink& sink, UErrorCode& status) const; + // To give LocalizedNumberFormatter format methods access to this class's constructor: friend class LocalizedNumberFormatter; @@ -2557,10 +2592,21 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue { friend struct impl::UFormattedNumberImpl; }; +#ifndef U_HIDE_DRAFT_API +// Note: This is draft ICU 65 +template<typename StringClass> +StringClass FormattedNumber::toDecimalNumber(UErrorCode& status) const { + StringClass result; + StringByteSink<StringClass> sink(&result); + toDecimalNumber(sink, status); + return result; +}; +#endif // U_HIDE_DRAFT_API + /** * See the main description in numberformatter.h for documentation and examples. * - * @draft ICU 60 + * @stable ICU 60 */ class U_I18N_API NumberFormatter final { public: @@ -2569,7 +2615,7 @@ class U_I18N_API NumberFormatter final { * the call site. * * @return An {@link UnlocalizedNumberFormatter}, to be used for chaining. - * @draft ICU 60 + * @stable ICU 60 */ static UnlocalizedNumberFormatter with(); @@ -2580,7 +2626,7 @@ class U_I18N_API NumberFormatter final { * @param locale * The locale from which to load formats and symbols for number formatting. * @return A {@link LocalizedNumberFormatter}, to be used for chaining. - * @draft ICU 60 + * @stable ICU 60 */ static LocalizedNumberFormatter withLocale(const Locale &locale); @@ -2596,10 +2642,11 @@ class U_I18N_API NumberFormatter final { * @param status * Set to U_NUMBER_SKELETON_SYNTAX_ERROR if the skeleton was invalid. * @return An UnlocalizedNumberFormatter, to be used for chaining. - * @draft ICU 62 + * @stable ICU 62 */ static UnlocalizedNumberFormatter forSkeleton(const UnicodeString& skeleton, UErrorCode& status); +#ifndef U_HIDE_DRAFT_API /** * Call this method at the beginning of a NumberFormatter fluent chain to create an instance based * on a given number skeleton string. @@ -2619,6 +2666,7 @@ class U_I18N_API NumberFormatter final { */ static UnlocalizedNumberFormatter forSkeleton(const UnicodeString& skeleton, UParseError& perror, UErrorCode& status); +#endif /** * Use factory methods instead of the constructor to create a NumberFormatter. @@ -2629,8 +2677,9 @@ class U_I18N_API NumberFormatter final { } // namespace number U_NAMESPACE_END -#endif // U_HIDE_DRAFT_API +#endif /* #if !UCONFIG_NO_FORMATTING */ + +#endif /* U_SHOW_CPLUSPLUS_API */ #endif // __NUMBERFORMATTER_H__ -#endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/unicode/numberrangeformatter.h b/deps/icu-small/source/i18n/unicode/numberrangeformatter.h index 47c4bfe3f5..e3a72aa8b2 100644 --- a/deps/icu-small/source/i18n/unicode/numberrangeformatter.h +++ b/deps/icu-small/source/i18n/unicode/numberrangeformatter.h @@ -1,10 +1,15 @@ // © 2018 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html -#if !UCONFIG_NO_FORMATTING #ifndef __NUMBERRANGEFORMATTER_H__ #define __NUMBERRANGEFORMATTER_H__ +#include "unicode/utypes.h" + +#if U_SHOW_CPLUSPLUS_API + +#if !UCONFIG_NO_FORMATTING + #include <atomic> #include "unicode/appendable.h" #include "unicode/fieldpos.h" @@ -12,8 +17,6 @@ #include "unicode/fpositer.h" #include "unicode/numberformatter.h" -#ifndef U_HIDE_DRAFT_API - /** * \file * \brief C++ API: Library for localized formatting of number, currency, and unit ranges. @@ -44,7 +47,7 @@ /** * Defines how to merge fields that are identical across the range sign. * - * @draft ICU 63 + * @stable ICU 63 */ typedef enum UNumberRangeCollapse { /** @@ -53,14 +56,14 @@ typedef enum UNumberRangeCollapse { * * The heuristics used for this option are subject to change over time. * - * @draft ICU 63 + * @stable ICU 63 */ UNUM_RANGE_COLLAPSE_AUTO, /** * Do not collapse any part of the number. Example: "3.2 thousand kilograms – 5.3 thousand kilograms" * - * @draft ICU 63 + * @stable ICU 63 */ UNUM_RANGE_COLLAPSE_NONE, @@ -68,7 +71,7 @@ typedef enum UNumberRangeCollapse { * Collapse the unit part of the number, but not the notation, if present. Example: "3.2 thousand – 5.3 thousand * kilograms" * - * @draft ICU 63 + * @stable ICU 63 */ UNUM_RANGE_COLLAPSE_UNIT, @@ -76,7 +79,7 @@ typedef enum UNumberRangeCollapse { * Collapse any field that is equal across the range sign. May introduce ambiguity on the magnitude of the * number. Example: "3.2 – 5.3 thousand kilograms" * - * @draft ICU 63 + * @stable ICU 63 */ UNUM_RANGE_COLLAPSE_ALL } UNumberRangeCollapse; @@ -85,14 +88,14 @@ typedef enum UNumberRangeCollapse { * Defines the behavior when the two numbers in the range are identical after rounding. To programmatically detect * when the identity fallback is used, compare the lower and upper BigDecimals via FormattedNumber. * - * @draft ICU 63 + * @stable ICU 63 * @see NumberRangeFormatter */ typedef enum UNumberRangeIdentityFallback { /** * Show the number as a single value rather than a range. Example: "$5" * - * @draft ICU 63 + * @stable ICU 63 */ UNUM_IDENTITY_FALLBACK_SINGLE_VALUE, @@ -100,7 +103,7 @@ typedef enum UNumberRangeIdentityFallback { * Show the number using a locale-sensitive approximation pattern. If the numbers were the same before rounding, * show the single value. Example: "~$5" or "$5" * - * @draft ICU 63 + * @stable ICU 63 */ UNUM_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, @@ -108,7 +111,7 @@ typedef enum UNumberRangeIdentityFallback { * Show the number using a locale-sensitive approximation pattern. Use the range pattern always, even if the * inputs are the same. Example: "~$5" * - * @draft ICU 63 + * @stable ICU 63 */ UNUM_IDENTITY_FALLBACK_APPROXIMATELY, @@ -116,7 +119,7 @@ typedef enum UNumberRangeIdentityFallback { * Show the number as the range of two equal values. Use the range pattern always, even if the inputs are the * same. Example (with RangeCollapse.NONE): "$5 – $5" * - * @draft ICU 63 + * @stable ICU 63 */ UNUM_IDENTITY_FALLBACK_RANGE } UNumberRangeIdentityFallback; @@ -125,14 +128,14 @@ typedef enum UNumberRangeIdentityFallback { * Used in the result class FormattedNumberRange to indicate to the user whether the numbers formatted in the range * were equal or not, and whether or not the identity fallback was applied. * - * @draft ICU 63 + * @stable ICU 63 * @see NumberRangeFormatter */ typedef enum UNumberRangeIdentityResult { /** * Used to indicate that the two numbers in the range were equal, even before any rounding rules were applied. * - * @draft ICU 63 + * @stable ICU 63 * @see NumberRangeFormatter */ UNUM_IDENTITY_RESULT_EQUAL_BEFORE_ROUNDING, @@ -140,7 +143,7 @@ typedef enum UNumberRangeIdentityResult { /** * Used to indicate that the two numbers in the range were equal, but only after rounding rules were applied. * - * @draft ICU 63 + * @stable ICU 63 * @see NumberRangeFormatter */ UNUM_IDENTITY_RESULT_EQUAL_AFTER_ROUNDING, @@ -148,7 +151,7 @@ typedef enum UNumberRangeIdentityResult { /** * Used to indicate that the two numbers in the range were not equal, even after rounding rules were applied. * - * @draft ICU 63 + * @stable ICU 63 * @see NumberRangeFormatter */ UNUM_IDENTITY_RESULT_NOT_EQUAL, @@ -254,7 +257,7 @@ class U_I18N_API NumberRangeFormatterSettings { * @param formatter * The formatter to use for both numbers in the range. * @return The fluent chain. - * @draft ICU 63 + * @stable ICU 63 */ Derived numberFormatterBoth(const UnlocalizedNumberFormatter &formatter) const &; @@ -265,7 +268,7 @@ class U_I18N_API NumberRangeFormatterSettings { * The formatter to use for both numbers in the range. * @return The fluent chain. * @see #numberFormatterBoth - * @draft ICU 63 + * @stable ICU 63 */ Derived numberFormatterBoth(const UnlocalizedNumberFormatter &formatter) &&; @@ -276,7 +279,7 @@ class U_I18N_API NumberRangeFormatterSettings { * The formatter to use for both numbers in the range. * @return The fluent chain. * @see #numberFormatterBoth - * @draft ICU 63 + * @stable ICU 63 */ Derived numberFormatterBoth(UnlocalizedNumberFormatter &&formatter) const &; @@ -287,7 +290,7 @@ class U_I18N_API NumberRangeFormatterSettings { * The formatter to use for both numbers in the range. * @return The fluent chain. * @see #numberFormatterBoth - * @draft ICU 63 + * @stable ICU 63 */ Derived numberFormatterBoth(UnlocalizedNumberFormatter &&formatter) &&; @@ -300,7 +303,7 @@ class U_I18N_API NumberRangeFormatterSettings { * @param formatterFirst * The formatter to use for the first number in the range. * @return The fluent chain. - * @draft ICU 63 + * @stable ICU 63 */ Derived numberFormatterFirst(const UnlocalizedNumberFormatter &formatterFirst) const &; @@ -311,7 +314,7 @@ class U_I18N_API NumberRangeFormatterSettings { * The formatter to use for the first number in the range. * @return The fluent chain. * @see #numberFormatterFirst - * @draft ICU 63 + * @stable ICU 63 */ Derived numberFormatterFirst(const UnlocalizedNumberFormatter &formatterFirst) &&; @@ -322,7 +325,7 @@ class U_I18N_API NumberRangeFormatterSettings { * The formatter to use for the first number in the range. * @return The fluent chain. * @see #numberFormatterFirst - * @draft ICU 63 + * @stable ICU 63 */ Derived numberFormatterFirst(UnlocalizedNumberFormatter &&formatterFirst) const &; @@ -333,7 +336,7 @@ class U_I18N_API NumberRangeFormatterSettings { * The formatter to use for the first number in the range. * @return The fluent chain. * @see #numberFormatterFirst - * @draft ICU 63 + * @stable ICU 63 */ Derived numberFormatterFirst(UnlocalizedNumberFormatter &&formatterFirst) &&; @@ -346,7 +349,7 @@ class U_I18N_API NumberRangeFormatterSettings { * @param formatterSecond * The formatter to use for the second number in the range. * @return The fluent chain. - * @draft ICU 63 + * @stable ICU 63 */ Derived numberFormatterSecond(const UnlocalizedNumberFormatter &formatterSecond) const &; @@ -357,7 +360,7 @@ class U_I18N_API NumberRangeFormatterSettings { * The formatter to use for the second number in the range. * @return The fluent chain. * @see #numberFormatterSecond - * @draft ICU 63 + * @stable ICU 63 */ Derived numberFormatterSecond(const UnlocalizedNumberFormatter &formatterSecond) &&; @@ -368,7 +371,7 @@ class U_I18N_API NumberRangeFormatterSettings { * The formatter to use for the second number in the range. * @return The fluent chain. * @see #numberFormatterSecond - * @draft ICU 63 + * @stable ICU 63 */ Derived numberFormatterSecond(UnlocalizedNumberFormatter &&formatterSecond) const &; @@ -379,7 +382,7 @@ class U_I18N_API NumberRangeFormatterSettings { * The formatter to use for the second number in the range. * @return The fluent chain. * @see #numberFormatterSecond - * @draft ICU 63 + * @stable ICU 63 */ Derived numberFormatterSecond(UnlocalizedNumberFormatter &&formatterSecond) &&; @@ -398,7 +401,7 @@ class U_I18N_API NumberRangeFormatterSettings { * @param collapse * The collapsing strategy to use for this range. * @return The fluent chain. - * @draft ICU 63 + * @stable ICU 63 */ Derived collapse(UNumberRangeCollapse collapse) const &; @@ -409,7 +412,7 @@ class U_I18N_API NumberRangeFormatterSettings { * The collapsing strategy to use for this range. * @return The fluent chain. * @see #collapse - * @draft ICU 63 + * @stable ICU 63 */ Derived collapse(UNumberRangeCollapse collapse) &&; @@ -431,7 +434,7 @@ class U_I18N_API NumberRangeFormatterSettings { * @param identityFallback * The strategy to use when formatting two numbers that end up being the same. * @return The fluent chain. - * @draft ICU 63 + * @stable ICU 63 */ Derived identityFallback(UNumberRangeIdentityFallback identityFallback) const &; @@ -442,10 +445,11 @@ class U_I18N_API NumberRangeFormatterSettings { * The strategy to use when formatting two numbers that end up being the same. * @return The fluent chain. * @see #identityFallback - * @draft ICU 63 + * @stable ICU 63 */ Derived identityFallback(UNumberRangeIdentityFallback identityFallback) &&; +#ifndef U_HIDE_DRAFT_API /** * Returns the current (Un)LocalizedNumberRangeFormatter as a LocalPointer * wrapping a heap-allocated copy of the current object. @@ -467,12 +471,13 @@ class U_I18N_API NumberRangeFormatterSettings { * @draft ICU 64 */ LocalPointer<Derived> clone() &&; +#endif /* U_HIDE_DRAFT_API */ /** * Sets the UErrorCode if an error occurred in the fluent chain. * Preserves older error codes in the outErrorCode. * @return TRUE if U_FAILURE(outErrorCode) - * @draft ICU 63 + * @stable ICU 63 */ UBool copyErrorTo(UErrorCode &outErrorCode) const { if (U_FAILURE(outErrorCode)) { @@ -501,7 +506,7 @@ class U_I18N_API NumberRangeFormatterSettings { * Instances of this class are immutable and thread-safe. * * @see NumberRangeFormatter - * @draft ICU 63 + * @stable ICU 63 */ class U_I18N_API UnlocalizedNumberRangeFormatter : public NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>, public UMemory { @@ -514,7 +519,7 @@ class U_I18N_API UnlocalizedNumberRangeFormatter * @param locale * The locale to use when loading data for number formatting. * @return The fluent chain. - * @draft ICU 63 + * @stable ICU 63 */ LocalizedNumberRangeFormatter locale(const icu::Locale &locale) const &; @@ -525,40 +530,40 @@ class U_I18N_API UnlocalizedNumberRangeFormatter * The locale to use when loading data for number formatting. * @return The fluent chain. * @see #locale - * @draft ICU 63 + * @stable ICU 63 */ LocalizedNumberRangeFormatter locale(const icu::Locale &locale) &&; /** * Default constructor: puts the formatter into a valid but undefined state. * - * @draft ICU 63 + * @stable ICU 63 */ UnlocalizedNumberRangeFormatter() = default; /** * Returns a copy of this UnlocalizedNumberRangeFormatter. - * @draft ICU 63 + * @stable ICU 63 */ UnlocalizedNumberRangeFormatter(const UnlocalizedNumberRangeFormatter &other); /** * Move constructor: * The source UnlocalizedNumberRangeFormatter will be left in a valid but undefined state. - * @draft ICU 63 + * @stable ICU 63 */ UnlocalizedNumberRangeFormatter(UnlocalizedNumberRangeFormatter&& src) U_NOEXCEPT; /** * Copy assignment operator. - * @draft ICU 63 + * @stable ICU 63 */ UnlocalizedNumberRangeFormatter& operator=(const UnlocalizedNumberRangeFormatter& other); /** * Move assignment operator: * The source UnlocalizedNumberRangeFormatter will be left in a valid but undefined state. - * @draft ICU 63 + * @stable ICU 63 */ UnlocalizedNumberRangeFormatter& operator=(UnlocalizedNumberRangeFormatter&& src) U_NOEXCEPT; @@ -582,7 +587,7 @@ class U_I18N_API UnlocalizedNumberRangeFormatter * Instances of this class are immutable and thread-safe. * * @see NumberFormatter - * @draft ICU 63 + * @stable ICU 63 */ class U_I18N_API LocalizedNumberRangeFormatter : public NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>, public UMemory { @@ -598,7 +603,7 @@ class U_I18N_API LocalizedNumberRangeFormatter * @param status * Set if an error occurs while formatting. * @return A FormattedNumberRange object; call .toString() to get the string. - * @draft ICU 63 + * @stable ICU 63 */ FormattedNumberRange formatFormattableRange( const Formattable& first, const Formattable& second, UErrorCode& status) const; @@ -606,33 +611,33 @@ class U_I18N_API LocalizedNumberRangeFormatter /** * Default constructor: puts the formatter into a valid but undefined state. * - * @draft ICU 63 + * @stable ICU 63 */ LocalizedNumberRangeFormatter() = default; /** * Returns a copy of this LocalizedNumberRangeFormatter. - * @draft ICU 63 + * @stable ICU 63 */ LocalizedNumberRangeFormatter(const LocalizedNumberRangeFormatter &other); /** * Move constructor: * The source LocalizedNumberRangeFormatter will be left in a valid but undefined state. - * @draft ICU 63 + * @stable ICU 63 */ LocalizedNumberRangeFormatter(LocalizedNumberRangeFormatter&& src) U_NOEXCEPT; /** * Copy assignment operator. - * @draft ICU 63 + * @stable ICU 63 */ LocalizedNumberRangeFormatter& operator=(const LocalizedNumberRangeFormatter& other); /** * Move assignment operator: * The source LocalizedNumberRangeFormatter will be left in a valid but undefined state. - * @draft ICU 63 + * @stable ICU 63 */ LocalizedNumberRangeFormatter& operator=(LocalizedNumberRangeFormatter&& src) U_NOEXCEPT; @@ -651,11 +656,11 @@ class U_I18N_API LocalizedNumberRangeFormatter void formatImpl(impl::UFormattedNumberRangeData& results, bool equalBeforeRounding, UErrorCode& status) const; -#endif +#endif /* U_HIDE_INTERNAL_API */ /** * Destruct this LocalizedNumberRangeFormatter, cleaning up any memory it might own. - * @draft ICU 63 + * @stable ICU 63 */ ~LocalizedNumberRangeFormatter(); @@ -690,7 +695,7 @@ class U_I18N_API LocalizedNumberRangeFormatter * * Instances of this class are immutable and thread-safe. * - * @draft ICU 63 + * @stable ICU 63 */ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue { public: @@ -700,7 +705,7 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue { * * For more information, see FormattedValue::toString() * - * @draft ICU 63 + * @stable ICU 63 */ UnicodeString toString(UErrorCode& status) const U_OVERRIDE; @@ -714,7 +719,7 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue { * * For more information, see FormattedValue::appendTo() * - * @draft ICU 63 + * @stable ICU 63 */ Appendable &appendTo(Appendable &appendable, UErrorCode& status) const U_OVERRIDE; @@ -722,6 +727,7 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue { /** @copydoc FormattedValue::nextPosition() */ UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE; +#ifndef U_HIDE_DRAFT_API /** * Determines the start (inclusive) and end (exclusive) indices of the next occurrence of the given * <em>field</em> in the output string. This allows you to determine the locations of, for example, @@ -799,6 +805,7 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue { * @see #getFirstDecimal */ UnicodeString getSecondDecimal(UErrorCode& status) const; +#endif // U_HIDE_DRAFT_API /** * Returns whether the pair of numbers was successfully formatted as a range or whether an identity fallback was @@ -806,7 +813,7 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue { * identity fallback was used. * * @return An indication the resulting identity situation in the formatted number range. - * @draft ICU 63 + * @stable ICU 63 * @see UNumberRangeIdentityFallback */ UNumberRangeIdentityResult getIdentityResult(UErrorCode& status) const; @@ -824,20 +831,20 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue { /** * Move constructor: * Leaves the source FormattedNumberRange in an undefined state. - * @draft ICU 63 + * @stable ICU 63 */ FormattedNumberRange(FormattedNumberRange&& src) U_NOEXCEPT; /** * Move assignment: * Leaves the source FormattedNumberRange in an undefined state. - * @draft ICU 63 + * @stable ICU 63 */ FormattedNumberRange& operator=(FormattedNumberRange&& src) U_NOEXCEPT; /** * Destruct an instance of FormattedNumberRange, cleaning up any memory it might own. - * @draft ICU 63 + * @stable ICU 63 */ ~FormattedNumberRange(); @@ -850,7 +857,6 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue { /** * Internal constructor from data type. Adopts the data pointer. - * @internal */ explicit FormattedNumberRange(impl::UFormattedNumberRangeData *results) : fData(results), fErrorCode(U_ZERO_ERROR) {} @@ -867,7 +873,7 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue { /** * See the main description in numberrangeformatter.h for documentation and examples. * - * @draft ICU 63 + * @stable ICU 63 */ class U_I18N_API NumberRangeFormatter final { public: @@ -876,7 +882,7 @@ class U_I18N_API NumberRangeFormatter final { * known at the call site. * * @return An {@link UnlocalizedNumberRangeFormatter}, to be used for chaining. - * @draft ICU 63 + * @stable ICU 63 */ static UnlocalizedNumberRangeFormatter with(); @@ -887,7 +893,7 @@ class U_I18N_API NumberRangeFormatter final { * @param locale * The locale from which to load formats and symbols for number range formatting. * @return A {@link LocalizedNumberRangeFormatter}, to be used for chaining. - * @draft ICU 63 + * @stable ICU 63 */ static LocalizedNumberRangeFormatter withLocale(const Locale &locale); @@ -900,8 +906,9 @@ class U_I18N_API NumberRangeFormatter final { } // namespace number U_NAMESPACE_END -#endif // U_HIDE_DRAFT_API +#endif /* #if !UCONFIG_NO_FORMATTING */ + +#endif /* U_SHOW_CPLUSPLUS_API */ #endif // __NUMBERRANGEFORMATTER_H__ -#endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/deps/icu-small/source/i18n/unicode/numfmt.h b/deps/icu-small/source/i18n/unicode/numfmt.h index d8704754dc..fbd4fb4e56 100644 --- a/deps/icu-small/source/i18n/unicode/numfmt.h +++ b/deps/icu-small/source/i18n/unicode/numfmt.h @@ -26,6 +26,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Compatibility APIs for number formatting. @@ -261,6 +263,14 @@ public: virtual ~NumberFormat(); /** + * Clones this object polymorphically. + * The caller owns the result and should delete it when done. + * @return clone, or nullptr if an error occurred + * @stable ICU 2.0 + */ + virtual NumberFormat* clone() const = 0; + + /** * Return true if the given Format objects are semantically equal. * Objects of different subclasses are considered unequal. * @return true if the given Format objects are semantically equal. @@ -639,7 +649,9 @@ public: * @param result Formattable to be set to the parse result. * If parse fails, return contents are undefined. * @param status Output parameter set to a failure error code - * when a failure occurs. + * when a failure occurs. The error code when the + * string fails to parse is U_INVALID_FORMAT_ERROR, + * unless overridden by a subclass. * @see NumberFormat::isParseIntegerOnly * @stable ICU 2.0 */ @@ -1255,5 +1267,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _NUMFMT //eof diff --git a/deps/icu-small/source/i18n/unicode/numsys.h b/deps/icu-small/source/i18n/unicode/numsys.h index 9e32478cf8..4fb7f044ed 100644 --- a/deps/icu-small/source/i18n/unicode/numsys.h +++ b/deps/icu-small/source/i18n/unicode/numsys.h @@ -20,6 +20,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: NumberingSystem object @@ -210,5 +212,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _NUMSYS //eof diff --git a/deps/icu-small/source/i18n/unicode/plurfmt.h b/deps/icu-small/source/i18n/unicode/plurfmt.h index 6b757c8841..7373476dca 100644 --- a/deps/icu-small/source/i18n/unicode/plurfmt.h +++ b/deps/icu-small/source/i18n/unicode/plurfmt.h @@ -16,6 +16,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: PluralFormat object @@ -448,7 +450,7 @@ public: * result and should delete it when done. * @stable ICU 4.0 */ - virtual Format* clone(void) const; + virtual PluralFormat* clone() const; /** * Formats a plural message for a number taken from a Formattable object. @@ -522,7 +524,7 @@ public: private: /** - * @internal + * @internal (private) */ class U_I18N_API PluralSelector : public UMemory { public: @@ -534,14 +536,11 @@ private: * @param number The number to be plural-formatted. * @param ec Error code. * @return The selected PluralFormat keyword. - * @internal + * @internal (private) */ virtual UnicodeString select(void *context, double number, UErrorCode& ec) const = 0; }; - /** - * @internal - */ class U_I18N_API PluralSelectorAdapter : public PluralSelector { public: PluralSelectorAdapter() : pluralRules(NULL) { @@ -549,7 +548,7 @@ private: virtual ~PluralSelectorAdapter(); - virtual UnicodeString select(void *context, double number, UErrorCode& /*ec*/) const; /**< @internal */ + virtual UnicodeString select(void *context, double number, UErrorCode& /*ec*/) const; void reset(); @@ -573,7 +572,7 @@ private: UnicodeString& format(const Formattable& numberObject, double number, UnicodeString& appendTo, FieldPosition& pos, - UErrorCode& status) const; /**< @internal */ + UErrorCode& status) const; /** * Finds the PluralFormat sub-message for the given number, or the "other" sub-message. @@ -601,5 +600,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _PLURFMT //eof diff --git a/deps/icu-small/source/i18n/unicode/plurrule.h b/deps/icu-small/source/i18n/unicode/plurrule.h index 04bf3970ba..a1553567ca 100644 --- a/deps/icu-small/source/i18n/unicode/plurrule.h +++ b/deps/icu-small/source/i18n/unicode/plurrule.h @@ -20,6 +20,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: PluralRules object @@ -533,5 +535,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _PLURRULE //eof diff --git a/deps/icu-small/source/i18n/unicode/rbnf.h b/deps/icu-small/source/i18n/unicode/rbnf.h index f7cd85a322..1144bd2fb8 100644 --- a/deps/icu-small/source/i18n/unicode/rbnf.h +++ b/deps/icu-small/source/i18n/unicode/rbnf.h @@ -12,6 +12,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Rule Based Number Format @@ -696,7 +698,7 @@ public: * @return A copy of the object. * @stable ICU 2.6 */ - virtual Format* clone(void) const; + virtual RuleBasedNumberFormat* clone() const; /** * Return true if the given Format objects are semantically equal. @@ -877,28 +879,6 @@ protected: * @param number The number, a DigitList format Decimal Floating Point. * @param appendTo Output parameter to receive result. * Result is appended to existing contents. - * @param posIter On return, can be used to iterate over positions - * of fields generated by this format call. - * @param status Output param filled with success/failure status. - * @return Reference to 'appendTo' parameter. - * @internal - */ - virtual UnicodeString& format(const number::impl::DecimalQuantity &number, - UnicodeString& appendTo, - FieldPositionIterator* posIter, - UErrorCode& status) const; - - /** - * Format a decimal number. - * The number is a DigitList wrapper onto a floating point decimal number. - * The default implementation in NumberFormat converts the decimal number - * to a double and formats that. Subclasses of NumberFormat that want - * to specifically handle big decimal numbers must override this method. - * class DecimalFormat does so. - * - * @param number The number, a DigitList format Decimal Floating Point. - * @param appendTo Output parameter to receive result. - * Result is appended to existing contents. * @param pos On input: an alignment field, if desired. * On output: the offsets of the alignment field. * @param status Output param filled with success/failure status. @@ -1135,5 +1115,7 @@ U_NAMESPACE_END /* U_HAVE_RBNF */ #endif +#endif /* U_SHOW_CPLUSPLUS_API */ + /* RBNF_H */ #endif diff --git a/deps/icu-small/source/i18n/unicode/rbtz.h b/deps/icu-small/source/i18n/unicode/rbtz.h index 542a7c140c..95fd7ab85d 100644 --- a/deps/icu-small/source/i18n/unicode/rbtz.h +++ b/deps/icu-small/source/i18n/unicode/rbtz.h @@ -11,6 +11,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Rule based customizable time zone @@ -121,7 +123,7 @@ public: * @return A new copy of this TimeZone object. * @stable ICU 3.8 */ - virtual TimeZone* clone(void) const; + virtual RuleBasedTimeZone* clone() const; /** * Returns the TimeZone's adjusted GMT offset (i.e., the number of milliseconds to add @@ -224,6 +226,7 @@ public: */ virtual UBool useDaylightTime(void) const; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Queries if the given date is in daylight savings time in * this time zone. @@ -238,6 +241,7 @@ public: * @deprecated ICU 2.4. Use Calendar::inDaylightTime() instead. */ virtual UBool inDaylightTime(UDate date, UErrorCode& status) const; +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Returns true if this zone has the same rule and offset as another zone. @@ -359,6 +363,8 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // RBTZ_H //eof diff --git a/deps/icu-small/source/i18n/unicode/regex.h b/deps/icu-small/source/i18n/unicode/regex.h index a0f9839fe7..75048af06c 100644 --- a/deps/icu-small/source/i18n/unicode/regex.h +++ b/deps/icu-small/source/i18n/unicode/regex.h @@ -44,6 +44,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_REGULAR_EXPRESSIONS #include "unicode/uobject.h" @@ -1876,4 +1878,7 @@ private: U_NAMESPACE_END #endif // UCONFIG_NO_REGULAR_EXPRESSIONS + +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif diff --git a/deps/icu-small/source/i18n/unicode/region.h b/deps/icu-small/source/i18n/unicode/region.h index ccd63901a5..66f5f92075 100644 --- a/deps/icu-small/source/i18n/unicode/region.h +++ b/deps/icu-small/source/i18n/unicode/region.h @@ -16,10 +16,12 @@ */ #include "unicode/utypes.h" -#include "unicode/uregion.h" + +#if U_SHOW_CPLUSPLUS_API #if !UCONFIG_NO_FORMATTING +#include "unicode/uregion.h" #include "unicode/uobject.h" #include "unicode/uniset.h" #include "unicode/unistr.h" @@ -219,6 +221,9 @@ private: U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ + +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // REGION_H //eof diff --git a/deps/icu-small/source/i18n/unicode/reldatefmt.h b/deps/icu-small/source/i18n/unicode/reldatefmt.h index cfcba09026..fb691a5451 100644 --- a/deps/icu-small/source/i18n/unicode/reldatefmt.h +++ b/deps/icu-small/source/i18n/unicode/reldatefmt.h @@ -15,6 +15,9 @@ #define __RELDATEFMT_H #include "unicode/utypes.h" + +#if U_SHOW_CPLUSPLUS_API + #include "unicode/uobject.h" #include "unicode/udisplaycontext.h" #include "unicode/ureldatefmt.h" @@ -166,12 +169,24 @@ typedef enum UDateAbsoluteUnit { */ UDAT_ABSOLUTE_NOW, -#ifndef U_HIDE_DRAFT_API /** * Quarter - * @draft ICU 63 + * @stable ICU 63 */ UDAT_ABSOLUTE_QUARTER, + +#ifndef U_HIDE_DRAFT_API + /** + * Hour + * @draft ICU 65 + */ + UDAT_ABSOLUTE_HOUR, + + /** + * Minute + * @draft ICU 65 + */ + UDAT_ABSOLUTE_MINUTE, #endif // U_HIDE_DRAFT_API #ifndef U_HIDE_DEPRECATED_API @@ -179,7 +194,7 @@ typedef enum UDateAbsoluteUnit { * One more than the highest normal UDateAbsoluteUnit value. * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ - UDAT_ABSOLUTE_UNIT_COUNT = UDAT_ABSOLUTE_NOW + 2 + UDAT_ABSOLUTE_UNIT_COUNT = UDAT_ABSOLUTE_NOW + 4 #endif // U_HIDE_DEPRECATED_API } UDateAbsoluteUnit; @@ -246,6 +261,7 @@ class SharedPluralRules; class SharedBreakIterator; class NumberFormat; class UnicodeString; +class FormattedRelativeDateTime; class FormattedRelativeDateTimeData; #ifndef U_HIDE_DRAFT_API @@ -743,4 +759,7 @@ U_NAMESPACE_END #endif /* !UCONFIG_NO_BREAK_ITERATION */ #endif /* !UCONFIG_NO_FORMATTING */ + +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif /* __RELDATEFMT_H */ diff --git a/deps/icu-small/source/i18n/unicode/scientificnumberformatter.h b/deps/icu-small/source/i18n/unicode/scientificnumberformatter.h index 6c99a24662..a56b8ca268 100644 --- a/deps/icu-small/source/i18n/unicode/scientificnumberformatter.h +++ b/deps/icu-small/source/i18n/unicode/scientificnumberformatter.h @@ -11,6 +11,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING @@ -157,7 +159,7 @@ public: class U_I18N_API SuperscriptStyle : public Style { public: - virtual Style *clone() const; + virtual SuperscriptStyle *clone() const; protected: virtual UnicodeString &format( const UnicodeString &original, @@ -175,7 +177,7 @@ public: : Style(), fBeginMarkup(beginMarkup), fEndMarkup(endMarkup) { } - virtual Style *clone() const; + virtual MarkupStyle *clone() const; protected: virtual UnicodeString &format( const UnicodeString &original, @@ -214,4 +216,7 @@ U_NAMESPACE_END #endif /* !UCONFIG_NO_FORMATTING */ + +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif diff --git a/deps/icu-small/source/i18n/unicode/search.h b/deps/icu-small/source/i18n/unicode/search.h index 12dd5c7727..986205c62f 100644 --- a/deps/icu-small/source/i18n/unicode/search.h +++ b/deps/icu-small/source/i18n/unicode/search.h @@ -14,6 +14,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: SearchIterator object. @@ -70,8 +72,7 @@ U_NAMESPACE_BEGIN * UErrorCode error = U_ZERO_ERROR; * for (int pos = iter->first(error); pos != USEARCH_DONE; * pos = iter->next(error)) { - * printf("Found match at %d pos, length is %d\n", pos, - * iter.getMatchLength()); + * printf("Found match at %d pos, length is %d\n", pos, iter.getMatchedLength()); * } * </code></pre> * @@ -573,4 +574,6 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_COLLATION */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif diff --git a/deps/icu-small/source/i18n/unicode/selfmt.h b/deps/icu-small/source/i18n/unicode/selfmt.h index 08e9d444ee..9b98f6db7a 100755 --- a/deps/icu-small/source/i18n/unicode/selfmt.h +++ b/deps/icu-small/source/i18n/unicode/selfmt.h @@ -18,9 +18,12 @@ #ifndef SELFMT #define SELFMT +#include "unicode/utypes.h" + +#if U_SHOW_CPLUSPLUS_API + #include "unicode/messagepattern.h" #include "unicode/numfmt.h" -#include "unicode/utypes.h" /** * \file @@ -272,7 +275,7 @@ public: * result and should delete it when done. * @stable ICU 4.4 */ - virtual Format* clone(void) const; + virtual SelectFormat* clone() const; /** * Format an object to produce a string. @@ -365,5 +368,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _SELFMT //eof diff --git a/deps/icu-small/source/i18n/unicode/simpletz.h b/deps/icu-small/source/i18n/unicode/simpletz.h index 7f5f1664cc..d7d4123187 100644 --- a/deps/icu-small/source/i18n/unicode/simpletz.h +++ b/deps/icu-small/source/i18n/unicode/simpletz.h @@ -28,6 +28,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: SimpleTimeZone is a concrete subclass of TimeZone. @@ -672,6 +674,7 @@ public: */ virtual UBool useDaylightTime(void) const; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Returns true if the given date is within the period when daylight savings time * is in effect; false otherwise. If the TimeZone doesn't observe daylight savings @@ -687,6 +690,7 @@ public: * @deprecated ICU 2.4. Use Calendar::inDaylightTime() instead. */ virtual UBool inDaylightTime(UDate date, UErrorCode& status) const; +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Return true if this zone has the same rules and offset as another zone. @@ -703,7 +707,7 @@ public: * @return A new copy of this TimeZone object. * @stable ICU 2.0 */ - virtual TimeZone* clone(void) const; + virtual SimpleTimeZone* clone() const; /** * Gets the first time zone transition after the base time. @@ -929,4 +933,6 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _SIMPLETZ diff --git a/deps/icu-small/source/i18n/unicode/smpdtfmt.h b/deps/icu-small/source/i18n/unicode/smpdtfmt.h index a015c5be5c..79fa817d5a 100644 --- a/deps/icu-small/source/i18n/unicode/smpdtfmt.h +++ b/deps/icu-small/source/i18n/unicode/smpdtfmt.h @@ -28,6 +28,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Format and parse dates in a language-independent manner. @@ -865,7 +867,7 @@ public: * @return A copy of the object. * @stable ICU 2.0 */ - virtual Format* clone(void) const; + virtual SimpleDateFormat* clone() const; /** * Return true if the given Format objects are semantically equal. Objects @@ -1643,7 +1645,7 @@ private: UBool fHaveDefaultCentury; - BreakIterator* fCapitalizationBrkIter; + const BreakIterator* fCapitalizationBrkIter; }; inline UDate @@ -1656,5 +1658,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // _SMPDTFMT //eof diff --git a/deps/icu-small/source/i18n/unicode/sortkey.h b/deps/icu-small/source/i18n/unicode/sortkey.h index 6895be7a2b..d2d3ca9fd5 100644 --- a/deps/icu-small/source/i18n/unicode/sortkey.h +++ b/deps/icu-small/source/i18n/unicode/sortkey.h @@ -25,6 +25,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Keys for comparing strings multiple times. @@ -337,4 +339,6 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_COLLATION */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif diff --git a/deps/icu-small/source/i18n/unicode/stsearch.h b/deps/icu-small/source/i18n/unicode/stsearch.h index 46bc51b30e..f396371143 100644 --- a/deps/icu-small/source/i18n/unicode/stsearch.h +++ b/deps/icu-small/source/i18n/unicode/stsearch.h @@ -14,6 +14,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Service for searching text based on RuleBasedCollator. @@ -119,8 +121,7 @@ U_NAMESPACE_BEGIN * pos != USEARCH_DONE; * pos = iter.next(error)) * { - * printf("Found match at %d pos, length is %d\n", pos, - * iter.getMatchLength()); + * printf("Found match at %d pos, length is %d\n", pos, iter.getMatchedLength()); * } * </code></pre> * <p> @@ -412,7 +413,7 @@ public: * @return cloned object * @stable ICU 2.0 */ - virtual SearchIterator * safeClone(void) const; + virtual StringSearch * safeClone() const; /** * ICU "poor man's RTTI", returns a UClassID for the actual class. @@ -502,4 +503,6 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_COLLATION */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif diff --git a/deps/icu-small/source/i18n/unicode/tblcoll.h b/deps/icu-small/source/i18n/unicode/tblcoll.h index 24ba213b41..f5dc135bc4 100644 --- a/deps/icu-small/source/i18n/unicode/tblcoll.h +++ b/deps/icu-small/source/i18n/unicode/tblcoll.h @@ -64,6 +64,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_COLLATION #include "unicode/coll.h" @@ -228,7 +230,7 @@ public: * @return a copy of this object, owned by the caller * @stable ICU 2.0 */ - virtual Collator* clone(void) const; + virtual RuleBasedCollator* clone() const; /** * Creates a collation element iterator for the source string. The caller of @@ -389,6 +391,7 @@ public: */ virtual int32_t hashCode() const; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Gets the locale of the Collator * @param type can be either requested, valid or actual locale. For more @@ -400,6 +403,7 @@ public: * @deprecated ICU 2.8 likely to change in ICU 3.0, based on feedback */ virtual Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const; +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Gets the tailoring rules for this collator. @@ -545,6 +549,7 @@ public: */ virtual UColReorderCode getMaxVariable() const; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Sets the variable top to the primary weight of the specified string. * @@ -592,6 +597,7 @@ public: * @deprecated ICU 53 Call setMaxVariable() instead. */ virtual void setVariableTop(uint32_t varTop, UErrorCode &status); +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Gets the variable top value of a Collator. @@ -874,4 +880,7 @@ private: U_NAMESPACE_END #endif // !UCONFIG_NO_COLLATION + +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // TBLCOLL_H diff --git a/deps/icu-small/source/i18n/unicode/timezone.h b/deps/icu-small/source/i18n/unicode/timezone.h index 237ed911d0..4d321186be 100644 --- a/deps/icu-small/source/i18n/unicode/timezone.h +++ b/deps/icu-small/source/i18n/unicode/timezone.h @@ -31,6 +31,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: TimeZone object @@ -321,10 +323,6 @@ public: * zone is set to the default host time zone. This call adopts the TimeZone object * passed in; the client is no longer responsible for deleting it. * - * <p>This function is not thread safe. It is an error for multiple threads - * to concurrently attempt to set the default time zone, or for any thread - * to attempt to reference the default zone while another thread is setting it. - * * @param zone A pointer to the new TimeZone object to use as the default. * @stable ICU 2.0 */ @@ -335,8 +333,6 @@ public: * Same as adoptDefault(), except that the TimeZone object passed in is NOT adopted; * the caller remains responsible for deleting it. * - * <p>See the thread safety note under adoptDefault(). - * * @param zone The given timezone. * @system * @stable ICU 2.0 @@ -726,6 +722,7 @@ public: */ virtual UBool useDaylightTime(void) const = 0; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Queries if the given date is in daylight savings time in * this time zone. @@ -740,6 +737,7 @@ public: * @deprecated ICU 2.4. Use Calendar::inDaylightTime() instead. */ virtual UBool inDaylightTime(UDate date, UErrorCode& status) const = 0; +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Returns true if this zone has the same rule and offset as another zone. @@ -758,7 +756,7 @@ public: * @return A new copy of this TimeZone object. * @stable ICU 2.0 */ - virtual TimeZone* clone(void) const = 0; + virtual TimeZone* clone() const = 0; /** * Return the class ID for this class. This is useful only for @@ -972,5 +970,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif //_TIMEZONE //eof diff --git a/deps/icu-small/source/i18n/unicode/tmunit.h b/deps/icu-small/source/i18n/unicode/tmunit.h index fa59f10473..2e949ddfbd 100644 --- a/deps/icu-small/source/i18n/unicode/tmunit.h +++ b/deps/icu-small/source/i18n/unicode/tmunit.h @@ -16,6 +16,9 @@ * \brief C++ API: time unit object */ +#include "unicode/utypes.h" + +#if U_SHOW_CPLUSPLUS_API #include "unicode/measunit.h" @@ -70,7 +73,7 @@ public: * Override clone. * @stable ICU 4.2 */ - virtual UObject* clone() const; + virtual TimeUnit* clone() const; /** * Copy operator. @@ -132,6 +135,8 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // __TMUNIT_H__ //eof // diff --git a/deps/icu-small/source/i18n/unicode/tmutamt.h b/deps/icu-small/source/i18n/unicode/tmutamt.h index 1717b7605f..5ce5922cea 100644 --- a/deps/icu-small/source/i18n/unicode/tmutamt.h +++ b/deps/icu-small/source/i18n/unicode/tmutamt.h @@ -16,11 +16,15 @@ * \brief C++ API: time unit amount object. */ -#include "unicode/measure.h" -#include "unicode/tmunit.h" +#include "unicode/utypes.h" + +#if U_SHOW_CPLUSPLUS_API #if !UCONFIG_NO_FORMATTING +#include "unicode/measure.h" +#include "unicode/tmunit.h" + U_NAMESPACE_BEGIN @@ -83,7 +87,7 @@ public: * @return a polymorphic clone of this object. The result will have the same class as returned by getDynamicClassID(). * @stable ICU 4.2 */ - virtual UObject* clone() const; + virtual TimeUnitAmount* clone() const; /** @@ -165,6 +169,8 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // __TMUTAMT_H__ //eof // diff --git a/deps/icu-small/source/i18n/unicode/tmutfmt.h b/deps/icu-small/source/i18n/unicode/tmutfmt.h index 8f245859a6..ad871f7c09 100644 --- a/deps/icu-small/source/i18n/unicode/tmutfmt.h +++ b/deps/icu-small/source/i18n/unicode/tmutfmt.h @@ -18,8 +18,9 @@ */ +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING -#ifndef U_HIDE_DEPRECATED_API #include "unicode/unistr.h" #include "unicode/tmunit.h" @@ -28,6 +29,7 @@ #include "unicode/numfmt.h" #include "unicode/plurrule.h" +#ifndef U_HIDE_DEPRECATED_API /** * Constants for various styles. @@ -124,7 +126,7 @@ public: * @return A copy of the object. * @deprecated ICU 53 */ - virtual Format* clone(void) const; + virtual TimeUnitFormat* clone() const; /** * Assignment operator @@ -244,5 +246,7 @@ U_NAMESPACE_END #endif /* U_HIDE_DEPRECATED_API */ #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // __TMUTFMT_H__ //eof diff --git a/deps/icu-small/source/i18n/unicode/translit.h b/deps/icu-small/source/i18n/unicode/translit.h index 6b4888145f..fe2568d50a 100644 --- a/deps/icu-small/source/i18n/unicode/translit.h +++ b/deps/icu-small/source/i18n/unicode/translit.h @@ -14,6 +14,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: Tranforms text from one format to another. @@ -1588,4 +1590,6 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_TRANSLITERATION */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif diff --git a/deps/icu-small/source/i18n/unicode/tzfmt.h b/deps/icu-small/source/i18n/unicode/tzfmt.h index d2aa768b8c..6d3863b1e5 100644 --- a/deps/icu-small/source/i18n/unicode/tzfmt.h +++ b/deps/icu-small/source/i18n/unicode/tzfmt.h @@ -16,6 +16,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING #include "unicode/format.h" @@ -305,7 +307,7 @@ public: * @return A copy of the object * @stable ICU 50 */ - virtual Format* clone() const; + virtual TimeZoneFormat* clone() const; /** * Creates an instance of <code>TimeZoneFormat</code> for the given locale. @@ -1094,4 +1096,7 @@ private: U_NAMESPACE_END #endif /* !UCONFIG_NO_FORMATTING */ + +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif diff --git a/deps/icu-small/source/i18n/unicode/tznames.h b/deps/icu-small/source/i18n/unicode/tznames.h index 399265d85a..860494221d 100644 --- a/deps/icu-small/source/i18n/unicode/tznames.h +++ b/deps/icu-small/source/i18n/unicode/tznames.h @@ -15,6 +15,8 @@ */ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING #include "unicode/uloc.h" @@ -411,4 +413,7 @@ public: U_NAMESPACE_END #endif + +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif diff --git a/deps/icu-small/source/i18n/unicode/tzrule.h b/deps/icu-small/source/i18n/unicode/tzrule.h index 171486f1c7..c6d6b9631f 100644 --- a/deps/icu-small/source/i18n/unicode/tzrule.h +++ b/deps/icu-small/source/i18n/unicode/tzrule.h @@ -16,6 +16,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING #include "unicode/uobject.h" @@ -45,7 +47,7 @@ public: * @return A copy of the object. * @stable ICU 3.8 */ - virtual TimeZoneRule* clone(void) const = 0; + virtual TimeZoneRule* clone() const = 0; /** * Return true if the given <code>TimeZoneRule</code> objects are semantically equal. Objects @@ -229,7 +231,7 @@ public: * @return A copy of the object. * @stable ICU 3.8 */ - virtual InitialTimeZoneRule* clone(void) const; + virtual InitialTimeZoneRule* clone() const; /** * Assignment operator. @@ -440,7 +442,7 @@ public: * @return A copy of the object. * @stable ICU 3.8 */ - virtual AnnualTimeZoneRule* clone(void) const; + virtual AnnualTimeZoneRule* clone() const; /** * Assignment operator. @@ -656,7 +658,7 @@ public: * @return A copy of the object. * @stable ICU 3.8 */ - virtual TimeArrayTimeZoneRule* clone(void) const; + virtual TimeArrayTimeZoneRule* clone() const; /** * Assignment operator. @@ -825,6 +827,8 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // TZRULE_H //eof diff --git a/deps/icu-small/source/i18n/unicode/tztrans.h b/deps/icu-small/source/i18n/unicode/tztrans.h index 1276d67c31..e87fea7c3c 100644 --- a/deps/icu-small/source/i18n/unicode/tztrans.h +++ b/deps/icu-small/source/i18n/unicode/tztrans.h @@ -16,6 +16,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + #if !UCONFIG_NO_FORMATTING #include "unicode/uobject.h" @@ -68,7 +70,7 @@ public: * @return A copy of the object. * @stable ICU 3.8 */ - TimeZoneTransition* clone(void) const; + TimeZoneTransition* clone() const; /** * Assignment operator. @@ -192,6 +194,8 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // TZTRANS_H //eof diff --git a/deps/icu-small/source/i18n/unicode/ucal.h b/deps/icu-small/source/i18n/unicode/ucal.h index 71120b7aed..eee2ae9e22 100644 --- a/deps/icu-small/source/i18n/unicode/ucal.h +++ b/deps/icu-small/source/i18n/unicode/ucal.h @@ -441,11 +441,13 @@ enum UCalendarDateFields { /* Do not conditionalize the following with #ifndef U_HIDE_DEPRECATED_API, * it is needed for layout of Calendar, DateFormat, and other objects */ +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * One more than the highest normal UCalendarDateFields value. * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ - UCAL_FIELD_COUNT, + UCAL_FIELD_COUNT, +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Field number indicating the @@ -657,6 +659,42 @@ ucal_getDefaultTimeZone(UChar* result, int32_t resultCapacity, UErrorCode* ec); U_STABLE void U_EXPORT2 ucal_setDefaultTimeZone(const UChar* zoneID, UErrorCode* ec); +#ifndef U_HIDE_DRAFT_API + +/** + * Return the current host time zone. The host time zone is detected from + * the current host system configuration by querying the host operating + * system. If the host system detection routines fail, or if they specify + * a TimeZone or TimeZone offset which is not recognized, then the special + * TimeZone "Etc/Unknown" is returned. + * + * Note that host time zone and the ICU default time zone can be different. + * + * The ICU default time zone does not change once initialized unless modified + * by calling `ucal_setDefaultTimeZone()` or with the C++ TimeZone API, + * `TimeZone::adoptDefault(TimeZone*)`. + * + * If the host operating system configuration has changed since ICU has + * initialized then the returned value can be different than the ICU default + * time zone, even if the default has not changed. + * + * <p>This function is not thread safe.</p> + * + * @param result A buffer to receive the result, or NULL + * @param resultCapacity The capacity of the result buffer + * @param ec input/output error code + * @return The result string length, not including the terminating + * null + * + * @see #UCAL_UNKNOWN_ZONE_ID + * + * @draft ICU 65 + */ +U_DRAFT int32_t U_EXPORT2 +ucal_getHostTimeZone(UChar *result, int32_t resultCapacity, UErrorCode *ec); + +#endif // U_HIDE_DRAFT_API + /** * Return the amount of time in milliseconds that the clock is * advanced during daylight savings time for the given time zone, or diff --git a/deps/icu-small/source/i18n/unicode/ucol.h b/deps/icu-small/source/i18n/unicode/ucol.h index f084ac61e6..34b5d2476a 100644 --- a/deps/icu-small/source/i18n/unicode/ucol.h +++ b/deps/icu-small/source/i18n/unicode/ucol.h @@ -344,11 +344,13 @@ typedef enum { /* Do not conditionalize the following with #ifndef U_HIDE_DEPRECATED_API, * it is needed for layout of RuleBasedCollator object. */ +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * One more than the highest normal UColAttribute value. * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ UCOL_ATTRIBUTE_COUNT +#endif // U_FORCE_HIDE_DEPRECATED_API } UColAttribute; /** Options for retrieving the rule string diff --git a/deps/icu-small/source/i18n/unicode/udat.h b/deps/icu-small/source/i18n/unicode/udat.h index c67a6d6d4b..bdbd080c00 100644 --- a/deps/icu-small/source/i18n/unicode/udat.h +++ b/deps/icu-small/source/i18n/unicode/udat.h @@ -923,11 +923,13 @@ typedef enum UDateFormatBooleanAttribute { /* Do not conditionalize the following with #ifndef U_HIDE_DEPRECATED_API, * it is needed for layout of DateFormat object. */ +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * One more than the highest normal UDateFormatBooleanAttribute value. * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ UDAT_BOOLEAN_ATTRIBUTE_COUNT = 4 +#endif // U_FORCE_HIDE_DEPRECATED_API } UDateFormatBooleanAttribute; /** diff --git a/deps/icu-small/source/i18n/unicode/udatpg.h b/deps/icu-small/source/i18n/unicode/udatpg.h index 238a27b4f4..81956d1270 100644 --- a/deps/icu-small/source/i18n/unicode/udatpg.h +++ b/deps/icu-small/source/i18n/unicode/udatpg.h @@ -88,11 +88,13 @@ typedef enum UDateTimePatternField { /* Do not conditionalize the following with #ifndef U_HIDE_DEPRECATED_API, * it is needed for layout of DateTimePatternGenerator object. */ +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * One more than the highest normal UDateTimePatternField value. * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ UDATPG_FIELD_COUNT +#endif // U_FORCE_HIDE_DEPRECATED_API } UDateTimePatternField; /** diff --git a/deps/icu-small/source/i18n/unicode/uformattedvalue.h b/deps/icu-small/source/i18n/unicode/uformattedvalue.h index d1c2ad1e49..172558f7fb 100644 --- a/deps/icu-small/source/i18n/unicode/uformattedvalue.h +++ b/deps/icu-small/source/i18n/unicode/uformattedvalue.h @@ -7,10 +7,11 @@ #include "unicode/utypes.h" #if !UCONFIG_NO_FORMATTING -#ifndef U_HIDE_DRAFT_API #include "unicode/ufieldpositer.h" +#ifndef U_HIDE_DRAFT_API + /** * \file * \brief C API: Abstract operations for localized strings. diff --git a/deps/icu-small/source/i18n/unicode/ulistformatter.h b/deps/icu-small/source/i18n/unicode/ulistformatter.h index 4327fd5ec1..0fbf72c9ff 100644 --- a/deps/icu-small/source/i18n/unicode/ulistformatter.h +++ b/deps/icu-small/source/i18n/unicode/ulistformatter.h @@ -41,7 +41,7 @@ struct UFormattedList; * @draft ICU 64 */ typedef struct UFormattedList UFormattedList; -#endif /* U_HIDE_DRAFT_API */ +#endif /* U_HIDE_DRAFT_API */ #ifndef U_HIDE_DRAFT_API /** @@ -61,7 +61,7 @@ typedef enum UListFormatterField { */ ULISTFMT_ELEMENT_FIELD } UListFormatterField; -#endif // U_HIDE_DRAFT_API +#endif /* U_HIDE_DRAFT_API */ /** * Open a new UListFormatter object using the rules for a given locale. diff --git a/deps/icu-small/source/i18n/unicode/unirepl.h b/deps/icu-small/source/i18n/unicode/unirepl.h index 8fb25d4689..61ee37f070 100644 --- a/deps/icu-small/source/i18n/unicode/unirepl.h +++ b/deps/icu-small/source/i18n/unicode/unirepl.h @@ -14,6 +14,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: UnicodeReplacer @@ -96,4 +98,6 @@ class U_I18N_API UnicodeReplacer /* not : public UObject because this is an inte U_NAMESPACE_END +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif diff --git a/deps/icu-small/source/i18n/unicode/unum.h b/deps/icu-small/source/i18n/unicode/unum.h index c03131f372..77cde03533 100644 --- a/deps/icu-small/source/i18n/unicode/unum.h +++ b/deps/icu-small/source/i18n/unicode/unum.h @@ -338,11 +338,13 @@ enum UCurrencySpacing { /* Do not conditionalize the following with #ifndef U_HIDE_DEPRECATED_API, * it is needed for layout of DecimalFormatSymbols object. */ +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * One more than the highest normal UCurrencySpacing value. * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420. */ UNUM_CURRENCY_SPACING_COUNT +#endif // U_FORCE_HIDE_DEPRECATED_API }; typedef enum UCurrencySpacing UCurrencySpacing; /**< @stable ICU 4.8 */ @@ -409,7 +411,7 @@ typedef enum UNumberFormatFields { * respectively. * * <p><strong>NOTE::</strong> New users with are strongly encouraged to - * use unumf_openWithSkeletonAndLocale instead of unum_open. + * use unumf_openForSkeletonAndLocale instead of unum_open. * * @param pattern A pattern specifying the format to use. * This parameter is ignored unless the style is diff --git a/deps/icu-small/source/i18n/unicode/unumberformatter.h b/deps/icu-small/source/i18n/unicode/unumberformatter.h index e4c21a4e4a..b27507f7a8 100644 --- a/deps/icu-small/source/i18n/unicode/unumberformatter.h +++ b/deps/icu-small/source/i18n/unicode/unumberformatter.h @@ -77,8 +77,6 @@ * </pre> */ - -#ifndef U_HIDE_DRAFT_API /** * An enum declaring how to render units, including currencies. Example outputs when formatting 123 USD and 123 * meters in <em>en-CA</em>: @@ -95,7 +93,7 @@ * <p> * This enum is similar to {@link UMeasureFormatWidth}. * - * @draft ICU 60 + * @stable ICU 60 */ typedef enum UNumberUnitWidth { /** @@ -107,7 +105,7 @@ typedef enum UNumberUnitWidth { * In CLDR, this option corresponds to the "Narrow" format for measure units and the "¤¤¤¤¤" placeholder for * currencies. * - * @draft ICU 60 + * @stable ICU 60 */ UNUM_UNIT_WIDTH_NARROW, @@ -123,7 +121,7 @@ typedef enum UNumberUnitWidth { * In CLDR, this option corresponds to the "Short" format for measure units and the "¤" placeholder for * currencies. * - * @draft ICU 60 + * @stable ICU 60 */ UNUM_UNIT_WIDTH_SHORT, @@ -134,7 +132,7 @@ typedef enum UNumberUnitWidth { * In CLDR, this option corresponds to the default format for measure units and the "¤¤¤" placeholder for * currencies. * - * @draft ICU 60 + * @stable ICU 60 */ UNUM_UNIT_WIDTH_FULL_NAME, @@ -145,7 +143,7 @@ typedef enum UNumberUnitWidth { * <p> * In CLDR, this option corresponds to the "¤¤" placeholder for currencies. * - * @draft ICU 60 + * @stable ICU 60 */ UNUM_UNIT_WIDTH_ISO_CODE, @@ -154,7 +152,7 @@ typedef enum UNumberUnitWidth { * monetary symbols and formats as with SHORT, but omit the currency symbol. For measure units, the behavior is * equivalent to not specifying the unit at all. * - * @draft ICU 60 + * @stable ICU 60 */ UNUM_UNIT_WIDTH_HIDDEN, @@ -165,9 +163,7 @@ typedef enum UNumberUnitWidth { */ UNUM_UNIT_WIDTH_COUNT } UNumberUnitWidth; -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** * An enum declaring the strategy for when and how to display grouping separators (i.e., the * separator, often a comma or period, after every 2-3 powers of ten). The choices are several @@ -192,13 +188,13 @@ typedef enum UNumberUnitWidth { * Note: This enum specifies the strategy for grouping sizes. To set which character to use as the * grouping separator, use the "symbols" setter. * - * @draft ICU 63 + * @stable ICU 63 */ typedef enum UNumberGroupingStrategy { /** * Do not display grouping separators in any locale. * - * @draft ICU 61 + * @stable ICU 61 */ UNUM_GROUPING_OFF, @@ -214,7 +210,7 @@ typedef enum UNumberGroupingStrategy { * Locale data is used to determine whether to separate larger numbers into groups of 2 * (customary in South Asia) or groups of 3 (customary in Europe and the Americas). * - * @draft ICU 61 + * @stable ICU 61 */ UNUM_GROUPING_MIN2, @@ -229,7 +225,7 @@ typedef enum UNumberGroupingStrategy { * Locale data is used to determine whether to separate larger numbers into groups of 2 * (customary in South Asia) or groups of 3 (customary in Europe and the Americas). * - * @draft ICU 61 + * @stable ICU 61 */ UNUM_GROUPING_AUTO, @@ -245,7 +241,7 @@ typedef enum UNumberGroupingStrategy { * Locale data is used to determine whether to separate larger numbers into groups of 2 * (customary in South Asia) or groups of 3 (customary in Europe and the Americas). * - * @draft ICU 61 + * @stable ICU 61 */ UNUM_GROUPING_ON_ALIGNED, @@ -253,7 +249,7 @@ typedef enum UNumberGroupingStrategy { * Use the Western defaults: groups of 3 and enabled for all numbers 1000 or greater. Do not use * locale data for determining the grouping strategy. * - * @draft ICU 61 + * @stable ICU 61 */ UNUM_GROUPING_THOUSANDS @@ -269,10 +265,6 @@ typedef enum UNumberGroupingStrategy { } UNumberGroupingStrategy; - -#endif /* U_HIDE_DRAFT_API */ - -#ifndef U_HIDE_DRAFT_API /** * An enum declaring how to denote positive and negative numbers. Example outputs when formatting * 123, 0, and -123 in <em>en-US</em>: @@ -290,14 +282,14 @@ typedef enum UNumberGroupingStrategy { * <p> * The exact format, including the position and the code point of the sign, differ by locale. * - * @draft ICU 60 + * @stable ICU 60 */ typedef enum UNumberSignDisplay { /** * Show the minus sign on negative numbers, and do not show the sign on positive numbers. This is the default * behavior. * - * @draft ICU 60 + * @stable ICU 60 */ UNUM_SIGN_AUTO, @@ -305,14 +297,14 @@ typedef enum UNumberSignDisplay { * Show the minus sign on negative numbers and the plus sign on positive numbers, including zero. * To hide the sign on zero, see {@link UNUM_SIGN_EXCEPT_ZERO}. * - * @draft ICU 60 + * @stable ICU 60 */ UNUM_SIGN_ALWAYS, /** * Do not show the sign on positive or negative numbers. * - * @draft ICU 60 + * @stable ICU 60 */ UNUM_SIGN_NEVER, @@ -328,7 +320,7 @@ typedef enum UNumberSignDisplay { * AUTO sign display strategy when formatting without a currency unit. This limitation may be lifted in the * future. * - * @draft ICU 60 + * @stable ICU 60 */ UNUM_SIGN_ACCOUNTING, @@ -338,24 +330,25 @@ typedef enum UNumberSignDisplay { * ACCOUNTING sign display strategy. To hide the sign on zero, see * {@link UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO}. * - * @draft ICU 60 + * @stable ICU 60 */ UNUM_SIGN_ACCOUNTING_ALWAYS, /** * Show the minus sign on negative numbers and the plus sign on positive numbers. Do not show a - * sign on zero. + * sign on zero or NaN, unless the sign bit is set (-0.0 gets a sign). * - * @draft ICU 61 + * @stable ICU 61 */ UNUM_SIGN_EXCEPT_ZERO, /** * Use the locale-dependent accounting format on negative numbers, and show the plus sign on - * positive numbers. Do not show a sign on zero. For more information on the accounting format, - * see the ACCOUNTING sign display strategy. + * positive numbers. Do not show a sign on zero or NaN, unless the sign bit is set (-0.0 gets a + * sign). For more information on the accounting format, see the ACCOUNTING sign display + * strategy. * - * @draft ICU 61 + * @stable ICU 61 */ UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO, @@ -366,9 +359,7 @@ typedef enum UNumberSignDisplay { */ UNUM_SIGN_COUNT } UNumberSignDisplay; -#endif /* U_HIDE_DRAFT_API */ -#ifndef U_HIDE_DRAFT_API /** * An enum declaring how to render the decimal separator. * @@ -378,21 +369,21 @@ typedef enum UNumberSignDisplay { * <li>UNUM_DECIMAL_SEPARATOR_ALWAYS: "1.", "1.1" * </ul> * - * @draft ICU 60 + * @stable ICU 60 */ typedef enum UNumberDecimalSeparatorDisplay { /** * Show the decimal separator when there are one or more digits to display after the separator, and do not show * it otherwise. This is the default behavior. * - * @draft ICU 60 + * @stable ICU 60 */ UNUM_DECIMAL_SEPARATOR_AUTO, /** * Always show the decimal separator, even if there are no digits to display after the separator. * - * @draft ICU 60 + * @stable ICU 60 */ UNUM_DECIMAL_SEPARATOR_ALWAYS, @@ -403,7 +394,6 @@ typedef enum UNumberDecimalSeparatorDisplay { */ UNUM_DECIMAL_SEPARATOR_COUNT } UNumberDecimalSeparatorDisplay; -#endif /* U_HIDE_DRAFT_API */ struct UNumberFormatter; /** @@ -649,6 +639,13 @@ unumf_resultGetAllFieldPositions(const UFormattedNumber* uresult, UFieldPosition UErrorCode* ec); +// TODO(ICU-20775): Propose this as API. +// NOTE: This is not currently implemented. +// U_DRAFT int32_t U_EXPORT2 +// unumf_resultToDecimalNumber(const UFormattedNumber* uresult, char* buffer, int32_t bufferCapacity, +// UErrorCode* ec); + + /** * Releases the UNumberFormatter created by unumf_openForSkeletonAndLocale(). * diff --git a/deps/icu-small/source/i18n/unicode/usearch.h b/deps/icu-small/source/i18n/unicode/usearch.h index 6b495ef001..d9d84b4f6a 100644 --- a/deps/icu-small/source/i18n/unicode/usearch.h +++ b/deps/icu-small/source/i18n/unicode/usearch.h @@ -24,7 +24,7 @@ * \file * \brief C API: StringSearch * - * C Apis for an engine that provides language-sensitive text searching based + * C APIs for an engine that provides language-sensitive text searching based * on the comparison rules defined in a <tt>UCollator</tt> data struct, * see <tt>ucol.h</tt>. This ensures that language eccentricity can be * handled, e.g. for the German collator, characters ß and SS will be matched @@ -55,7 +55,7 @@ * <p> * This search has APIs similar to that of other text iteration mechanisms * such as the break iterators in <tt>ubrk.h</tt>. Using these - * APIs, it is easy to scan through text looking for all occurances of + * APIs, it is easy to scan through text looking for all occurrences of * a given pattern. This search iterator allows changing of direction by * calling a <tt>reset</tt> followed by a <tt>next</tt> or <tt>previous</tt>. * Though a direction change can occur without calling <tt>reset</tt> first, @@ -130,7 +130,7 @@ * pos = usearch_next(search, &status)) * { * printf("Found match at %d pos, length is %d\n", pos, - * usearch_getMatchLength(search)); + * usearch_getMatchedLength(search)); * } * } * @@ -479,7 +479,7 @@ U_STABLE int32_t U_EXPORT2 usearch_getMatchedLength( * possible. If the buffer fits the matched text exactly, a null-termination * is not possible, then a U_STRING_NOT_TERMINATED_ERROR set in status. * Pre-flighting can be either done with length = 0 or the API -* <tt>usearch_getMatchLength</tt>. +* <tt>usearch_getMatchedLength</tt>. * @param strsrch search iterator data struct * @param result UChar buffer to store the matched string * @param resultCapacity length of the result buffer @@ -766,7 +766,7 @@ U_STABLE void U_EXPORT2 usearch_reset(UStringSearch *strsrch); #ifndef U_HIDE_INTERNAL_API /** * Simple forward search for the pattern, starting at a specified index, - * and using using a default set search options. + * and using a default set search options. * * This is an experimental function, and is not an official part of the * ICU API. @@ -783,7 +783,7 @@ U_STABLE void U_EXPORT2 usearch_reset(UStringSearch *strsrch); * are part of a combining sequence, as described below. * * A match will not include a partial combining sequence. Combining - * character sequences are considered to be inseperable units, + * character sequences are considered to be inseparable units, * and either match the pattern completely, or are considered to not match * at all. Thus, for example, an A followed a combining accent mark will * not be found when searching for a plain (unaccented) A. (unless @@ -792,7 +792,7 @@ U_STABLE void U_EXPORT2 usearch_reset(UStringSearch *strsrch); * When beginning a search, the initial starting position, startIdx, * is assumed to be an acceptable match boundary with respect to * combining characters. A combining sequence that spans across the - * starting point will not supress a match beginning at startIdx. + * starting point will not suppress a match beginning at startIdx. * * Characters that expand to multiple collation elements * (German sharp-S becoming 'ss', or the composed forms of accented @@ -843,7 +843,7 @@ U_INTERNAL UBool U_EXPORT2 usearch_search(UStringSearch *strsrch, * are part of a combining sequence, as described below. * * A match will not include a partial combining sequence. Combining - * character sequences are considered to be inseperable units, + * character sequences are considered to be inseparable units, * and either match the pattern completely, or are considered to not match * at all. Thus, for example, an A followed a combining accent mark will * not be found when searching for a plain (unaccented) A. (unless @@ -852,7 +852,7 @@ U_INTERNAL UBool U_EXPORT2 usearch_search(UStringSearch *strsrch, * When beginning a search, the initial starting position, startIdx, * is assumed to be an acceptable match boundary with respect to * combining characters. A combining sequence that spans across the - * starting point will not supress a match beginning at startIdx. + * starting point will not suppress a match beginning at startIdx. * * Characters that expand to multiple collation elements * (German sharp-S becoming 'ss', or the composed forms of accented diff --git a/deps/icu-small/source/i18n/unicode/uspoof.h b/deps/icu-small/source/i18n/unicode/uspoof.h index d15ba4b242..63a13387b0 100644 --- a/deps/icu-small/source/i18n/unicode/uspoof.h +++ b/deps/icu-small/source/i18n/unicode/uspoof.h @@ -353,6 +353,8 @@ * @stable ICU 4.6 */ +U_CDECL_BEGIN + struct USpoofChecker; /** * @stable ICU 4.2 @@ -471,7 +473,6 @@ typedef enum USpoofChecks { */ USPOOF_MIXED_NUMBERS = 128, -#ifndef U_HIDE_DRAFT_API /** * Check that an identifier does not have a combining character following a character in which that * combining character would be hidden; for example 'i' followed by a U+0307 combining dot. @@ -489,10 +490,9 @@ typedef enum USpoofChecks { * * This list and the number of combing characters considered by this check may grow over time. * - * @draft ICU 62 + * @stable ICU 62 */ USPOOF_HIDDEN_OVERLAY = 256, -#endif /* U_HIDE_DRAFT_API */ /** * Enable all spoof checks. @@ -674,25 +674,6 @@ uspoof_openFromSource(const char *confusables, int32_t confusablesLen, U_STABLE void U_EXPORT2 uspoof_close(USpoofChecker *sc); -#if U_SHOW_CPLUSPLUS_API - -U_NAMESPACE_BEGIN - -/** - * \class LocalUSpoofCheckerPointer - * "Smart pointer" class, closes a USpoofChecker via uspoof_close(). - * For most methods see the LocalPointerBase base class. - * - * @see LocalPointerBase - * @see LocalPointer - * @stable ICU 4.4 - */ -U_DEFINE_LOCAL_OPEN_POINTER(LocalUSpoofCheckerPointer, USpoofChecker, uspoof_close); - -U_NAMESPACE_END - -#endif - /** * Clone a Spoof Checker. The clone will be set to perform the same checks * as the original source. @@ -901,54 +882,6 @@ U_STABLE const USet * U_EXPORT2 uspoof_getAllowedChars(const USpoofChecker *sc, UErrorCode *status); -#if U_SHOW_CPLUSPLUS_API -/** - * Limit the acceptable characters to those specified by a Unicode Set. - * Any previously specified character limit is - * is replaced by the new settings. This includes limits on - * characters that were set with the uspoof_setAllowedLocales() function. - * - * The USPOOF_CHAR_LIMIT test is automatically enabled for this - * USoofChecker by this function. - * - * @param sc The USpoofChecker - * @param chars A Unicode Set containing the list of - * characters that are permitted. Ownership of the set - * remains with the caller. The incoming set is cloned by - * this function, so there are no restrictions on modifying - * or deleting the UnicodeSet after calling this function. - * @param status The error code, set if this function encounters a problem. - * @stable ICU 4.2 - */ -U_STABLE void U_EXPORT2 -uspoof_setAllowedUnicodeSet(USpoofChecker *sc, const icu::UnicodeSet *chars, UErrorCode *status); - - -/** - * Get a UnicodeSet for the characters permitted in an identifier. - * This corresponds to the limits imposed by the Set Allowed Characters / - * UnicodeSet functions. Limitations imposed by other checks will not be - * reflected in the set returned by this function. - * - * The returned set will be frozen, meaning that it cannot be modified - * by the caller. - * - * Ownership of the returned set remains with the Spoof Detector. The - * returned set will become invalid if the spoof detector is closed, - * or if a new set of allowed characters is specified. - * - * - * @param sc The USpoofChecker - * @param status The error code, set if this function encounters a problem. - * @return A UnicodeSet containing the characters that are permitted by - * the USPOOF_CHAR_LIMIT test. - * @stable ICU 4.2 - */ -U_STABLE const icu::UnicodeSet * U_EXPORT2 -uspoof_getAllowedUnicodeSet(const USpoofChecker *sc, UErrorCode *status); -#endif - - /** * Check the specified string for possible security issues. * The text to be checked will typically be an identifier of some sort. @@ -1027,43 +960,6 @@ uspoof_checkUTF8(const USpoofChecker *sc, UErrorCode *status); -#if U_SHOW_CPLUSPLUS_API -/** - * Check the specified string for possible security issues. - * The text to be checked will typically be an identifier of some sort. - * The set of checks to be performed is specified with uspoof_setChecks(). - * - * \note - * Consider using the newer API, {@link uspoof_check2UnicodeString}, instead. - * The newer API exposes additional information from the check procedure - * and is otherwise identical to this method. - * - * @param sc The USpoofChecker - * @param id A identifier to be checked for possible security issues. - * @param position Deprecated in ICU 51. Always returns zero. - * Originally, an out parameter for the index of the first - * string position that failed a check. - * This parameter may be NULL. - * @param status The error code, set if an error occurred while attempting to - * perform the check. - * Spoofing or security issues detected with the input string are - * not reported here, but through the function's return value. - * @return An integer value with bits set for any potential security - * or spoofing issues detected. The bits are defined by - * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) - * will be zero if the input string passes all of the - * enabled checks. - * @see uspoof_check2UnicodeString - * @stable ICU 4.2 - */ -U_STABLE int32_t U_EXPORT2 -uspoof_checkUnicodeString(const USpoofChecker *sc, - const icu::UnicodeString &id, - int32_t *position, - UErrorCode *status); -#endif - - /** * Check the specified string for possible security issues. * The text to be checked will typically be an identifier of some sort. @@ -1135,39 +1031,6 @@ uspoof_check2UTF8(const USpoofChecker *sc, USpoofCheckResult* checkResult, UErrorCode *status); -#if U_SHOW_CPLUSPLUS_API -/** - * Check the specified string for possible security issues. - * The text to be checked will typically be an identifier of some sort. - * The set of checks to be performed is specified with uspoof_setChecks(). - * - * @param sc The USpoofChecker - * @param id A identifier to be checked for possible security issues. - * @param checkResult An instance of USpoofCheckResult to be filled with - * details about the identifier. Can be NULL. - * @param status The error code, set if an error occurred while attempting to - * perform the check. - * Spoofing or security issues detected with the input string are - * not reported here, but through the function's return value. - * @return An integer value with bits set for any potential security - * or spoofing issues detected. The bits are defined by - * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) - * will be zero if the input string passes all of the - * enabled checks. Any information in this bitmask will be - * consistent with the information saved in the optional - * checkResult parameter. - * @see uspoof_openCheckResult - * @see uspoof_check2 - * @see uspoof_check2UTF8 - * @stable ICU 58 - */ -U_STABLE int32_t U_EXPORT2 -uspoof_check2UnicodeString(const USpoofChecker *sc, - const icu::UnicodeString &id, - USpoofCheckResult* checkResult, - UErrorCode *status); -#endif - /** * Create a USpoofCheckResult, used by the {@link uspoof_check2} class of functions to return * information about the identifier. Information includes: @@ -1199,32 +1062,6 @@ uspoof_openCheckResult(UErrorCode *status); U_STABLE void U_EXPORT2 uspoof_closeCheckResult(USpoofCheckResult *checkResult); -#if U_SHOW_CPLUSPLUS_API - -U_NAMESPACE_BEGIN - -/** - * \class LocalUSpoofCheckResultPointer - * "Smart pointer" class, closes a USpoofCheckResult via `uspoof_closeCheckResult()`. - * For most methods see the LocalPointerBase base class. - * - * @see LocalPointerBase - * @see LocalPointer - * @stable ICU 58 - */ - -/** - * \cond - * Note: Doxygen is giving a bogus warning on this U_DEFINE_LOCAL_OPEN_POINTER. - * For now, suppress with a Doxygen cond - */ -U_DEFINE_LOCAL_OPEN_POINTER(LocalUSpoofCheckResultPointer, USpoofCheckResult, uspoof_closeCheckResult); -/** \endcond */ - -U_NAMESPACE_END - -#endif - /** * Indicates which of the spoof check(s) have failed. The value is a bitwise OR of the constants for the tests * in question: USPOOF_RESTRICTION_LEVEL, USPOOF_CHAR_LIMIT, and so on. @@ -1355,36 +1192,6 @@ uspoof_areConfusableUTF8(const USpoofChecker *sc, -#if U_SHOW_CPLUSPLUS_API -/** - * A version of {@link uspoof_areConfusable} accepting UnicodeStrings. - * - * @param sc The USpoofChecker - * @param s1 The first of the two identifiers to be compared for - * confusability. The strings are in UTF-8 format. - * @param s2 The second of the two identifiers to be compared for - * confusability. The strings are in UTF-8 format. - * @param status The error code, set if an error occurred while attempting to - * perform the check. - * Confusability of the identifiers is not reported here, - * but through this function's return value. - * @return An integer value with bit(s) set corresponding to - * the type of confusability found, as defined by - * enum USpoofChecks. Zero is returned if the identifiers - * are not confusable. - * - * @stable ICU 4.2 - * - * @see uspoof_areConfusable - */ -U_STABLE int32_t U_EXPORT2 -uspoof_areConfusableUnicodeString(const USpoofChecker *sc, - const icu::UnicodeString &s1, - const icu::UnicodeString &s2, - UErrorCode *status); -#endif - - /** * Get the "skeleton" for an identifier. * Skeletons are a transformation of the input identifier; @@ -1463,38 +1270,6 @@ uspoof_getSkeletonUTF8(const USpoofChecker *sc, char *dest, int32_t destCapacity, UErrorCode *status); -#if U_SHOW_CPLUSPLUS_API -/** - * Get the "skeleton" for an identifier. - * Skeletons are a transformation of the input identifier; - * Two identifiers are confusable if their skeletons are identical. - * See Unicode UAX #39 for additional information. - * - * Using skeletons directly makes it possible to quickly check - * whether an identifier is confusable with any of some large - * set of existing identifiers, by creating an efficiently - * searchable collection of the skeletons. - * - * @param sc The USpoofChecker. - * @param type Deprecated in ICU 58. You may pass any number. - * Originally, controlled which of the Unicode confusable data - * tables to use. - * @param id The input identifier whose skeleton will be computed. - * @param dest The output identifier, to receive the skeleton string. - * @param status The error code, set if an error occurred while attempting to - * perform the check. - * @return A reference to the destination (skeleton) string. - * - * @stable ICU 4.2 - */ -U_I18N_API icu::UnicodeString & U_EXPORT2 -uspoof_getSkeletonUnicodeString(const USpoofChecker *sc, - uint32_t type, - const icu::UnicodeString &id, - icu::UnicodeString &dest, - UErrorCode *status); -#endif /* U_SHOW_CPLUSPLUS_API */ - /** * Get the set of Candidate Characters for Inclusion in Identifiers, as defined * in http://unicode.org/Public/security/latest/xidmodifications.txt @@ -1525,8 +1300,243 @@ uspoof_getInclusionSet(UErrorCode *status); U_STABLE const USet * U_EXPORT2 uspoof_getRecommendedSet(UErrorCode *status); +/** + * Serialize the data for a spoof detector into a chunk of memory. + * The flattened spoof detection tables can later be used to efficiently + * instantiate a new Spoof Detector. + * + * The serialized spoof checker includes only the data compiled from the + * Unicode data tables by uspoof_openFromSource(); it does not include + * include any other state or configuration that may have been set. + * + * @param sc the Spoof Detector whose data is to be serialized. + * @param data a pointer to 32-bit-aligned memory to be filled with the data, + * can be NULL if capacity==0 + * @param capacity the number of bytes available at data, + * or 0 for preflighting + * @param status an in/out ICU UErrorCode; possible errors include: + * - U_BUFFER_OVERFLOW_ERROR if the data storage block is too small for serialization + * - U_ILLEGAL_ARGUMENT_ERROR the data or capacity parameters are bad + * @return the number of bytes written or needed for the spoof data + * + * @see utrie2_openFromSerialized() + * @stable ICU 4.2 + */ +U_STABLE int32_t U_EXPORT2 +uspoof_serialize(USpoofChecker *sc, + void *data, int32_t capacity, + UErrorCode *status); + +U_CDECL_END + #if U_SHOW_CPLUSPLUS_API +U_NAMESPACE_BEGIN + +/** + * \class LocalUSpoofCheckerPointer + * "Smart pointer" class, closes a USpoofChecker via uspoof_close(). + * For most methods see the LocalPointerBase base class. + * + * @see LocalPointerBase + * @see LocalPointer + * @stable ICU 4.4 + */ +/** + * \cond + * Note: Doxygen is giving a bogus warning on this U_DEFINE_LOCAL_OPEN_POINTER. + * For now, suppress with a Doxygen cond + */ +U_DEFINE_LOCAL_OPEN_POINTER(LocalUSpoofCheckerPointer, USpoofChecker, uspoof_close); +/** \endcond */ + +/** + * \class LocalUSpoofCheckResultPointer + * "Smart pointer" class, closes a USpoofCheckResult via `uspoof_closeCheckResult()`. + * For most methods see the LocalPointerBase base class. + * + * @see LocalPointerBase + * @see LocalPointer + * @stable ICU 58 + */ + +/** + * \cond + * Note: Doxygen is giving a bogus warning on this U_DEFINE_LOCAL_OPEN_POINTER. + * For now, suppress with a Doxygen cond + */ +U_DEFINE_LOCAL_OPEN_POINTER(LocalUSpoofCheckResultPointer, USpoofCheckResult, uspoof_closeCheckResult); +/** \endcond */ + +U_NAMESPACE_END + +/** + * Limit the acceptable characters to those specified by a Unicode Set. + * Any previously specified character limit is + * is replaced by the new settings. This includes limits on + * characters that were set with the uspoof_setAllowedLocales() function. + * + * The USPOOF_CHAR_LIMIT test is automatically enabled for this + * USoofChecker by this function. + * + * @param sc The USpoofChecker + * @param chars A Unicode Set containing the list of + * characters that are permitted. Ownership of the set + * remains with the caller. The incoming set is cloned by + * this function, so there are no restrictions on modifying + * or deleting the UnicodeSet after calling this function. + * @param status The error code, set if this function encounters a problem. + * @stable ICU 4.2 + */ +U_STABLE void U_EXPORT2 +uspoof_setAllowedUnicodeSet(USpoofChecker *sc, const icu::UnicodeSet *chars, UErrorCode *status); + + +/** + * Get a UnicodeSet for the characters permitted in an identifier. + * This corresponds to the limits imposed by the Set Allowed Characters / + * UnicodeSet functions. Limitations imposed by other checks will not be + * reflected in the set returned by this function. + * + * The returned set will be frozen, meaning that it cannot be modified + * by the caller. + * + * Ownership of the returned set remains with the Spoof Detector. The + * returned set will become invalid if the spoof detector is closed, + * or if a new set of allowed characters is specified. + * + * + * @param sc The USpoofChecker + * @param status The error code, set if this function encounters a problem. + * @return A UnicodeSet containing the characters that are permitted by + * the USPOOF_CHAR_LIMIT test. + * @stable ICU 4.2 + */ +U_STABLE const icu::UnicodeSet * U_EXPORT2 +uspoof_getAllowedUnicodeSet(const USpoofChecker *sc, UErrorCode *status); + +/** + * Check the specified string for possible security issues. + * The text to be checked will typically be an identifier of some sort. + * The set of checks to be performed is specified with uspoof_setChecks(). + * + * \note + * Consider using the newer API, {@link uspoof_check2UnicodeString}, instead. + * The newer API exposes additional information from the check procedure + * and is otherwise identical to this method. + * + * @param sc The USpoofChecker + * @param id A identifier to be checked for possible security issues. + * @param position Deprecated in ICU 51. Always returns zero. + * Originally, an out parameter for the index of the first + * string position that failed a check. + * This parameter may be NULL. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * Spoofing or security issues detected with the input string are + * not reported here, but through the function's return value. + * @return An integer value with bits set for any potential security + * or spoofing issues detected. The bits are defined by + * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) + * will be zero if the input string passes all of the + * enabled checks. + * @see uspoof_check2UnicodeString + * @stable ICU 4.2 + */ +U_STABLE int32_t U_EXPORT2 +uspoof_checkUnicodeString(const USpoofChecker *sc, + const icu::UnicodeString &id, + int32_t *position, + UErrorCode *status); + +/** + * Check the specified string for possible security issues. + * The text to be checked will typically be an identifier of some sort. + * The set of checks to be performed is specified with uspoof_setChecks(). + * + * @param sc The USpoofChecker + * @param id A identifier to be checked for possible security issues. + * @param checkResult An instance of USpoofCheckResult to be filled with + * details about the identifier. Can be NULL. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * Spoofing or security issues detected with the input string are + * not reported here, but through the function's return value. + * @return An integer value with bits set for any potential security + * or spoofing issues detected. The bits are defined by + * enum USpoofChecks. (returned_value & USPOOF_ALL_CHECKS) + * will be zero if the input string passes all of the + * enabled checks. Any information in this bitmask will be + * consistent with the information saved in the optional + * checkResult parameter. + * @see uspoof_openCheckResult + * @see uspoof_check2 + * @see uspoof_check2UTF8 + * @stable ICU 58 + */ +U_STABLE int32_t U_EXPORT2 +uspoof_check2UnicodeString(const USpoofChecker *sc, + const icu::UnicodeString &id, + USpoofCheckResult* checkResult, + UErrorCode *status); + +/** + * A version of {@link uspoof_areConfusable} accepting UnicodeStrings. + * + * @param sc The USpoofChecker + * @param s1 The first of the two identifiers to be compared for + * confusability. The strings are in UTF-8 format. + * @param s2 The second of the two identifiers to be compared for + * confusability. The strings are in UTF-8 format. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * Confusability of the identifiers is not reported here, + * but through this function's return value. + * @return An integer value with bit(s) set corresponding to + * the type of confusability found, as defined by + * enum USpoofChecks. Zero is returned if the identifiers + * are not confusable. + * + * @stable ICU 4.2 + * + * @see uspoof_areConfusable + */ +U_STABLE int32_t U_EXPORT2 +uspoof_areConfusableUnicodeString(const USpoofChecker *sc, + const icu::UnicodeString &s1, + const icu::UnicodeString &s2, + UErrorCode *status); + +/** + * Get the "skeleton" for an identifier. + * Skeletons are a transformation of the input identifier; + * Two identifiers are confusable if their skeletons are identical. + * See Unicode UAX #39 for additional information. + * + * Using skeletons directly makes it possible to quickly check + * whether an identifier is confusable with any of some large + * set of existing identifiers, by creating an efficiently + * searchable collection of the skeletons. + * + * @param sc The USpoofChecker. + * @param type Deprecated in ICU 58. You may pass any number. + * Originally, controlled which of the Unicode confusable data + * tables to use. + * @param id The input identifier whose skeleton will be computed. + * @param dest The output identifier, to receive the skeleton string. + * @param status The error code, set if an error occurred while attempting to + * perform the check. + * @return A reference to the destination (skeleton) string. + * + * @stable ICU 4.2 + */ +U_I18N_API icu::UnicodeString & U_EXPORT2 +uspoof_getSkeletonUnicodeString(const USpoofChecker *sc, + uint32_t type, + const icu::UnicodeString &id, + icu::UnicodeString &dest, + UErrorCode *status); + /** * Get the set of Candidate Characters for Inclusion in Identifiers, as defined * in http://unicode.org/Public/security/latest/xidmodifications.txt @@ -1559,34 +1569,6 @@ uspoof_getRecommendedUnicodeSet(UErrorCode *status); #endif /* U_SHOW_CPLUSPLUS_API */ -/** - * Serialize the data for a spoof detector into a chunk of memory. - * The flattened spoof detection tables can later be used to efficiently - * instantiate a new Spoof Detector. - * - * The serialized spoof checker includes only the data compiled from the - * Unicode data tables by uspoof_openFromSource(); it does not include - * include any other state or configuration that may have been set. - * - * @param sc the Spoof Detector whose data is to be serialized. - * @param data a pointer to 32-bit-aligned memory to be filled with the data, - * can be NULL if capacity==0 - * @param capacity the number of bytes available at data, - * or 0 for preflighting - * @param status an in/out ICU UErrorCode; possible errors include: - * - U_BUFFER_OVERFLOW_ERROR if the data storage block is too small for serialization - * - U_ILLEGAL_ARGUMENT_ERROR the data or capacity parameters are bad - * @return the number of bytes written or needed for the spoof data - * - * @see utrie2_openFromSerialized() - * @stable ICU 4.2 - */ -U_STABLE int32_t U_EXPORT2 -uspoof_serialize(USpoofChecker *sc, - void *data, int32_t capacity, - UErrorCode *status); - - -#endif +#endif /* UCONFIG_NO_NORMALIZATION */ #endif /* USPOOF_H */ diff --git a/deps/icu-small/source/i18n/unicode/utrans.h b/deps/icu-small/source/i18n/unicode/utrans.h index 7672b4428f..56640eda96 100644 --- a/deps/icu-small/source/i18n/unicode/utrans.h +++ b/deps/icu-small/source/i18n/unicode/utrans.h @@ -142,7 +142,7 @@ typedef struct UTransPosition { int32_t contextLimit; /** - * Beginning index, inclusive, of the text to be transliteratd. + * Beginning index, inclusive, of the text to be transliterated. * INPUT/OUTPUT parameter: This parameter is advanced past * characters that have already been transliterated by a * transliteration operation. @@ -151,7 +151,7 @@ typedef struct UTransPosition { int32_t start; /** - * Ending index, exclusive, of the text to be transliteratd. + * Ending index, exclusive, of the text to be transliterated. * INPUT/OUTPUT parameter: This parameter is updated to reflect * changes in the length of the text, but points to the same * logical position in the text. @@ -389,7 +389,7 @@ utrans_trans(const UTransliterator* trans, /** * Transliterate the portion of the UReplaceable text buffer that can - * be transliterated unambiguosly. This method is typically called + * be transliterated unambiguously. This method is typically called * after new text has been inserted, e.g. as a result of a keyboard * event. The transliterator will try to transliterate characters of * <code>rep</code> between <code>index.cursor</code> and @@ -454,8 +454,7 @@ utrans_transIncremental(const UTransliterator* trans, * zero-terminated. Upon return, the new length is stored in * *textLength. If textLength is NULL then the string is assumed to * be zero-terminated. - * @param textCapacity a pointer to the length of the text buffer. - * Upon return, + * @param textCapacity the length of the text buffer * @param start the beginning index, inclusive; <code>0 <= start <= * limit</code>. * @param limit pointer to the ending index, exclusive; <code>start <= @@ -479,7 +478,7 @@ utrans_transUChars(const UTransliterator* trans, /** * Transliterate the portion of the UChar* text buffer that can be - * transliterated unambiguosly. See utrans_transIncremental(). The + * transliterated unambiguously. See utrans_transIncremental(). The * string is passed in in a UChar* buffer. The string is modified in * place. If the result is longer than textCapacity, it is truncated. * The actual length of the result is returned in *textLength, if diff --git a/deps/icu-small/source/i18n/unicode/vtzone.h b/deps/icu-small/source/i18n/unicode/vtzone.h index 5d16177868..43a5652d6a 100644 --- a/deps/icu-small/source/i18n/unicode/vtzone.h +++ b/deps/icu-small/source/i18n/unicode/vtzone.h @@ -11,6 +11,8 @@ #include "unicode/utypes.h" +#if U_SHOW_CPLUSPLUS_API + /** * \file * \brief C++ API: RFC2445 VTIMEZONE support @@ -185,7 +187,7 @@ public: * @return A new copy of this TimeZone object. * @stable ICU 3.8 */ - virtual TimeZone* clone(void) const; + virtual VTimeZone* clone() const; /** * Returns the TimeZone's adjusted GMT offset (i.e., the number of milliseconds to add @@ -288,6 +290,7 @@ public: */ virtual UBool useDaylightTime(void) const; +#ifndef U_FORCE_HIDE_DEPRECATED_API /** * Queries if the given date is in daylight savings time in * this time zone. @@ -302,6 +305,7 @@ public: * @deprecated ICU 2.4. Use Calendar::inDaylightTime() instead. */ virtual UBool inDaylightTime(UDate date, UErrorCode& status) const; +#endif // U_FORCE_HIDE_DEPRECATED_API /** * Returns true if this zone has the same rule and offset as another zone. @@ -453,5 +457,7 @@ U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ +#endif /* U_SHOW_CPLUSPLUS_API */ + #endif // VTZONE_H //eof diff --git a/deps/icu-small/source/i18n/unum.cpp b/deps/icu-small/source/i18n/unum.cpp index 907a1cd95e..ba3d519162 100644 --- a/deps/icu-small/source/i18n/unum.cpp +++ b/deps/icu-small/source/i18n/unum.cpp @@ -135,6 +135,11 @@ unum_open( UNumberFormatStyle style, *status = U_MEMORY_ALLOCATION_ERROR; } + if (U_FAILURE(*status) && retVal != NULL) { + delete retVal; + retVal = NULL; + } + return reinterpret_cast<UNumberFormat *>(retVal); } diff --git a/deps/icu-small/source/i18n/usearch.cpp b/deps/icu-small/source/i18n/usearch.cpp index 0e9b876d2b..1b22e201e5 100644 --- a/deps/icu-small/source/i18n/usearch.cpp +++ b/deps/icu-small/source/i18n/usearch.cpp @@ -317,7 +317,7 @@ inline uint16_t initializePatternCETable(UStringSearch *strsrch, uprv_free(pattern->ces); } - uint16_t offset = 0; + uint32_t offset = 0; uint16_t result = 0; int32_t ce; @@ -388,7 +388,7 @@ inline uint16_t initializePatternPCETable(UStringSearch *strsrch, uprv_free(pattern->pces); } - uint16_t offset = 0; + uint32_t offset = 0; uint16_t result = 0; int64_t pce; @@ -1351,7 +1351,7 @@ inline int getUnblockedAccentIndex(UChar *accents, int32_t *accentsindex) * @param destinationlength target array size, returning the appended length * @param source1 null-terminated first array * @param source2 second array -* @param source2length length of seond array +* @param source2length length of second array * @param source3 null-terminated third array * @param status error status if any * @return new destination array, destination if there was no new allocation @@ -1560,7 +1560,7 @@ inline void cleanUpSafeText(const UStringSearch *strsrch, UChar *safetext, /** * Take the rearranged end accents and tries matching. If match failed at -* a seperate preceding set of accents (seperated from the rearranged on by +* a separate preceding set of accents (separated from the rearranged on by * at least a base character) then we rearrange the preceding accents and * tries matching again. * We allow skipping of the ends of the accent set if the ces do not match. @@ -2220,7 +2220,7 @@ int32_t doPreviousCanonicalSuffixMatch(UStringSearch *strsrch, /** * Take the rearranged start accents and tries matching. If match failed at -* a seperate following set of accents (seperated from the rearranged on by +* a separate following set of accents (separated from the rearranged on by * at least a base character) then we rearrange the preceding accents and * tries matching again. * We allow skipping of the ends of the accent set if the ces do not match. @@ -3544,7 +3544,12 @@ const CEI *CEIBuffer::get(int32_t index) { // Verify that it is the next one in sequence, which is all // that is allowed. if (index != limitIx) { - UPRV_UNREACHABLE; + U_ASSERT(FALSE); + // TODO: In ICU 64 the above assert was changed to use UPRV_UNREACHABLE instead + // which unconditionally calls abort(). However, there were cases where this was + // being hit. This change is reverted for now, restoring the existing behavior. + // ICU-20792 tracks the follow-up work/further investigation on this. + return NULL; } // Manage the circular CE buffer indexing @@ -3581,7 +3586,12 @@ const CEI *CEIBuffer::getPrevious(int32_t index) { // Verify that it is the next one in sequence, which is all // that is allowed. if (index != limitIx) { - UPRV_UNREACHABLE; + U_ASSERT(FALSE); + // TODO: In ICU 64 the above assert was changed to use UPRV_UNREACHABLE instead + // which unconditionally calls abort(). However, there were cases where this was + // being hit. This change is reverted for now, restoring the existing behavior. + // ICU-20792 tracks the follow-up work/further investigation on this. + return NULL; } // Manage the circular CE buffer indexing @@ -3852,7 +3862,7 @@ U_CAPI UBool U_EXPORT2 usearch_search(UStringSearch *strsrch, #endif // Input parameter sanity check. - // TODO: should input indicies clip to the text length + // TODO: should input indices clip to the text length // in the same way that UText does. if(strsrch->pattern.cesLength == 0 || startIdx < 0 || @@ -4014,7 +4024,7 @@ U_CAPI UBool U_EXPORT2 usearch_search(UStringSearch *strsrch, // Check for the start of the match being within an Collation Element Expansion, // meaning that the first char of the match is only partially matched. - // With exapnsions, the first CE will report the index of the source + // With expansions, the first CE will report the index of the source // character, and all subsequent (expansions) CEs will report the source index of the // _following_ character. int32_t secondIx = firstCEI->highIndex; diff --git a/deps/icu-small/source/i18n/uspoof.cpp b/deps/icu-small/source/i18n/uspoof.cpp index c8fbec27bb..c44c60028b 100644 --- a/deps/icu-small/source/i18n/uspoof.cpp +++ b/deps/icu-small/source/i18n/uspoof.cpp @@ -349,7 +349,7 @@ uspoof_setAllowedUnicodeSet(USpoofChecker *sc, const UnicodeSet *chars, UErrorCo *status = U_ILLEGAL_ARGUMENT_ERROR; return; } - UnicodeSet *clonedSet = static_cast<UnicodeSet *>(chars->clone()); + UnicodeSet *clonedSet = chars->clone(); if (clonedSet == NULL || clonedSet->isBogus()) { *status = U_MEMORY_ALLOCATION_ERROR; return; diff --git a/deps/icu-small/source/i18n/uspoof_impl.cpp b/deps/icu-small/source/i18n/uspoof_impl.cpp index 85a028bdfa..3c1f84a19b 100644 --- a/deps/icu-small/source/i18n/uspoof_impl.cpp +++ b/deps/icu-small/source/i18n/uspoof_impl.cpp @@ -82,7 +82,7 @@ SpoofImpl::SpoofImpl(const SpoofImpl &src, UErrorCode &status) : if (src.fSpoofData != NULL) { fSpoofData = src.fSpoofData->addReference(); } - fAllowedCharsSet = static_cast<const UnicodeSet *>(src.fAllowedCharsSet->clone()); + fAllowedCharsSet = src.fAllowedCharsSet->clone(); fAllowedLocales = uprv_strdup(src.fAllowedLocales); if (fAllowedCharsSet == NULL || fAllowedLocales == NULL) { status = U_MEMORY_ALLOCATION_ERROR; @@ -193,7 +193,7 @@ void SpoofImpl::setAllowedLocales(const char *localesList, UErrorCode &status) { } // Store the updated spoof checker state. - tmpSet = static_cast<UnicodeSet *>(allowedChars.clone()); + tmpSet = allowedChars.clone(); const char *tmpLocalesList = uprv_strdup(localesList); if (tmpSet == NULL || tmpLocalesList == NULL) { status = U_MEMORY_ALLOCATION_ERROR; diff --git a/deps/icu-small/source/i18n/vtzone.cpp b/deps/icu-small/source/i18n/vtzone.cpp index e39eada51b..bda3d1115e 100644 --- a/deps/icu-small/source/i18n/vtzone.cpp +++ b/deps/icu-small/source/i18n/vtzone.cpp @@ -965,7 +965,7 @@ VTimeZone::VTimeZone(const VTimeZone& source) tzurl(source.tzurl), lastmod(source.lastmod), olsonzid(source.olsonzid), icutzver(source.icutzver) { if (source.tz != NULL) { - tz = (BasicTimeZone*)source.tz->clone(); + tz = source.tz->clone(); } if (source.vtzlines != NULL) { UErrorCode status = U_ZERO_ERROR; @@ -1007,7 +1007,7 @@ VTimeZone::operator=(const VTimeZone& right) { tz = NULL; } if (right.tz != NULL) { - tz = (BasicTimeZone*)right.tz->clone(); + tz = right.tz->clone(); } if (vtzlines != NULL) { delete vtzlines; @@ -1092,7 +1092,7 @@ VTimeZone::createVTimeZoneFromBasicTimeZone(const BasicTimeZone& basic_time_zone status = U_MEMORY_ALLOCATION_ERROR; return NULL; } - vtz->tz = (BasicTimeZone *)basic_time_zone.clone(); + vtz->tz = basic_time_zone.clone(); if (vtz->tz == NULL) { status = U_MEMORY_ALLOCATION_ERROR; delete vtz; @@ -1177,8 +1177,8 @@ VTimeZone::writeSimple(UDate time, UnicodeString& result, UErrorCode& status) co writeSimple(time, writer, status); } -TimeZone* -VTimeZone::clone(void) const { +VTimeZone* +VTimeZone::clone() const { return new VTimeZone(*this); } @@ -1957,7 +1957,7 @@ VTimeZone::writeZone(VTZWriter& w, BasicTimeZone& basictz, && (atzrule = dynamic_cast<const AnnualTimeZoneRule *>(tzt.getTo())) != NULL && atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR ) { - finalDstRule = (AnnualTimeZoneRule*)tzt.getTo()->clone(); + finalDstRule = atzrule->clone(); } if (dstCount > 0) { if (year == dstStartYear + dstCount @@ -2008,7 +2008,7 @@ VTimeZone::writeZone(VTZWriter& w, BasicTimeZone& basictz, && (atzrule = dynamic_cast<const AnnualTimeZoneRule *>(tzt.getTo())) != NULL && atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR ) { - finalStdRule = (AnnualTimeZoneRule*)tzt.getTo()->clone(); + finalStdRule = atzrule->clone(); } if (stdCount > 0) { if (year == stdStartYear + stdCount diff --git a/deps/icu-small/source/i18n/windtfmt.cpp b/deps/icu-small/source/i18n/windtfmt.cpp index 983fd46c12..c35adc0987 100644 --- a/deps/icu-small/source/i18n/windtfmt.cpp +++ b/deps/icu-small/source/i18n/windtfmt.cpp @@ -213,7 +213,7 @@ Win32DateFormat &Win32DateFormat::operator=(const Win32DateFormat &other) return *this; } -Format *Win32DateFormat::clone(void) const +Win32DateFormat *Win32DateFormat::clone() const { return new Win32DateFormat(*this); } diff --git a/deps/icu-small/source/i18n/windtfmt.h b/deps/icu-small/source/i18n/windtfmt.h index 43b6fe6dba..f13a1ae687 100644 --- a/deps/icu-small/source/i18n/windtfmt.h +++ b/deps/icu-small/source/i18n/windtfmt.h @@ -48,7 +48,7 @@ public: virtual ~Win32DateFormat(); - virtual Format *clone(void) const; + virtual Win32DateFormat *clone() const; Win32DateFormat &operator=(const Win32DateFormat &other); diff --git a/deps/icu-small/source/i18n/winnmfmt.cpp b/deps/icu-small/source/i18n/winnmfmt.cpp index b1724b62c2..1ae2310123 100644 --- a/deps/icu-small/source/i18n/winnmfmt.cpp +++ b/deps/icu-small/source/i18n/winnmfmt.cpp @@ -294,7 +294,7 @@ Win32NumberFormat &Win32NumberFormat::operator=(const Win32NumberFormat &other) return *this; } -Format *Win32NumberFormat::clone(void) const +Win32NumberFormat *Win32NumberFormat::clone() const { return new Win32NumberFormat(*this); } diff --git a/deps/icu-small/source/i18n/winnmfmt.h b/deps/icu-small/source/i18n/winnmfmt.h index 7ea5da9170..8cf59ccf48 100644 --- a/deps/icu-small/source/i18n/winnmfmt.h +++ b/deps/icu-small/source/i18n/winnmfmt.h @@ -44,7 +44,7 @@ public: virtual ~Win32NumberFormat(); - virtual Format *clone(void) const; + virtual Win32NumberFormat *clone() const; Win32NumberFormat &operator=(const Win32NumberFormat &other); diff --git a/deps/icu-small/source/i18n/zonemeta.cpp b/deps/icu-small/source/i18n/zonemeta.cpp index 0e3ee89316..72c590f424 100644 --- a/deps/icu-small/source/i18n/zonemeta.cpp +++ b/deps/icu-small/source/i18n/zonemeta.cpp @@ -30,10 +30,7 @@ #include "olsontz.h" #include "uinvchar.h" -static icu::UMutex *gZoneMetaLock() { - static icu::UMutex m = U_MUTEX_INITIALIZER; - return &m; -} +static icu::UMutex gZoneMetaLock; // CLDR Canonical ID mapping table static UHashtable *gCanonicalIDCache = NULL; @@ -266,11 +263,11 @@ ZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) { } // Check if it was already cached - umtx_lock(gZoneMetaLock()); + umtx_lock(&gZoneMetaLock); { canonicalID = (const UChar *)uhash_get(gCanonicalIDCache, utzid); } - umtx_unlock(gZoneMetaLock()); + umtx_unlock(&gZoneMetaLock); if (canonicalID != NULL) { return canonicalID; @@ -351,7 +348,7 @@ ZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) { U_ASSERT(canonicalID != NULL); // canocanilD must be non-NULL here // Put the resolved canonical ID to the cache - umtx_lock(gZoneMetaLock()); + umtx_lock(&gZoneMetaLock); { const UChar* idInCache = (const UChar *)uhash_get(gCanonicalIDCache, utzid); if (idInCache == NULL) { @@ -371,7 +368,7 @@ ZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) { } } } - umtx_unlock(gZoneMetaLock()); + umtx_unlock(&gZoneMetaLock); } return canonicalID; @@ -449,14 +446,14 @@ ZoneMeta::getCanonicalCountry(const UnicodeString &tzid, UnicodeString &country, // Check if it was already cached UBool cached = FALSE; UBool singleZone = FALSE; - umtx_lock(gZoneMetaLock()); + umtx_lock(&gZoneMetaLock); { singleZone = cached = gSingleZoneCountries->contains((void*)region); if (!cached) { cached = gMultiZonesCountries->contains((void*)region); } } - umtx_unlock(gZoneMetaLock()); + umtx_unlock(&gZoneMetaLock); if (!cached) { // We need to go through all zones associated with the region. @@ -475,7 +472,7 @@ ZoneMeta::getCanonicalCountry(const UnicodeString &tzid, UnicodeString &country, delete ids; // Cache the result - umtx_lock(gZoneMetaLock()); + umtx_lock(&gZoneMetaLock); { UErrorCode ec = U_ZERO_ERROR; if (singleZone) { @@ -488,7 +485,7 @@ ZoneMeta::getCanonicalCountry(const UnicodeString &tzid, UnicodeString &country, } } } - umtx_unlock(gZoneMetaLock()); + umtx_unlock(&gZoneMetaLock); } if (singleZone) { @@ -575,11 +572,11 @@ ZoneMeta::getMetazoneMappings(const UnicodeString &tzid) { // get the mapping from cache const UVector *result = NULL; - umtx_lock(gZoneMetaLock()); + umtx_lock(&gZoneMetaLock); { result = (UVector*) uhash_get(gOlsonToMeta, tzidUChars); } - umtx_unlock(gZoneMetaLock()); + umtx_unlock(&gZoneMetaLock); if (result != NULL) { return result; @@ -593,7 +590,7 @@ ZoneMeta::getMetazoneMappings(const UnicodeString &tzid) { } // put the new one into the cache - umtx_lock(gZoneMetaLock()); + umtx_lock(&gZoneMetaLock); { // make sure it's already created result = (UVector*) uhash_get(gOlsonToMeta, tzidUChars); @@ -621,7 +618,7 @@ ZoneMeta::getMetazoneMappings(const UnicodeString &tzid) { delete tmpResult; } } - umtx_unlock(gZoneMetaLock()); + umtx_unlock(&gZoneMetaLock); return result; } |