From 57913822e0cc20562dc534b3618838c0c25394ec Mon Sep 17 00:00:00 2001 From: Shane Carr Date: Sun, 10 Sep 2017 02:02:02 +0000 Subject: [PATCH] ICU-13177 Internal changes to existing icu4c source. X-SVN-Rev: 40378 --- icu4c/source/common/unicode/localpointer.h | 35 ++++ icu4c/source/common/unicode/simpleformatter.h | 9 + icu4c/source/i18n/Makefile.in | 3 +- icu4c/source/i18n/measunit.cpp | 182 +++++++++--------- icu4c/source/i18n/nounit.cpp | 42 ++++ icu4c/source/i18n/ucln_in.h | 1 + icu4c/source/i18n/unicode/fpositer.h | 6 +- icu4c/source/i18n/unicode/measunit.h | 6 + icu4c/source/i18n/unicode/nounit.h | 110 +++++++++++ 9 files changed, 303 insertions(+), 91 deletions(-) create mode 100644 icu4c/source/i18n/nounit.cpp create mode 100644 icu4c/source/i18n/unicode/nounit.h diff --git a/icu4c/source/common/unicode/localpointer.h b/icu4c/source/common/unicode/localpointer.h index e17ee3d886e..741f9333bd8 100644 --- a/icu4c/source/common/unicode/localpointer.h +++ b/icu4c/source/common/unicode/localpointer.h @@ -311,6 +311,41 @@ public: } }; +/** + * A version of LocalPointer that allows for implicit copying. + * + * Inside the copy constructor, the pointer is new'd, and the resulting LocalPointer + * adopts the new object. The original LocalPointer is unchanged and continues to own + * its copy of the object. + * + * @see LocalPointer + * @internal + * @deprecated ICU 60 This API is a technical preview. It may change in an upcoming release. + */ +template +class CopyableLocalPointer : public LocalPointer { + public: + // Inherit constructors + using LocalPointer::LocalPointer; + + // Inherited constructors don't include default arguments. Define a default constructor. + CopyableLocalPointer() : LocalPointer(NULL) {}; + + /** + * Creates a new local pointer. This constructor calls T's copy constructor + * and takes ownership of the new object. + * + * If memory allocation fails, the resulting pointer will be null. + */ + CopyableLocalPointer(const CopyableLocalPointer& other) { + if (other.ptr == NULL) { + LocalPointerBase::ptr = NULL; + } else { + LocalPointerBase::ptr = new T(*other.ptr); + } + } +}; + /** * "Smart pointer" class, deletes objects via the C++ array delete[] operator. * For most methods see the LocalPointerBase base class. diff --git a/icu4c/source/common/unicode/simpleformatter.h b/icu4c/source/common/unicode/simpleformatter.h index 26eae015252..c74bd414890 100644 --- a/icu4c/source/common/unicode/simpleformatter.h +++ b/icu4c/source/common/unicode/simpleformatter.h @@ -261,6 +261,15 @@ public: return getTextWithNoArguments(compiledPattern.getBuffer(), compiledPattern.length()); } + /** + * Gets the internal compiled pattern string. + * @internal + * @deprecated ICU 60 This API is ICU internal only. + */ + UnicodeString getCompiledPattern() const { + return compiledPattern; + } + private: /** * Binary representation of the compiled pattern. diff --git a/icu4c/source/i18n/Makefile.in b/icu4c/source/i18n/Makefile.in index 2fe9b3d8de7..fa0e47c0539 100644 --- a/icu4c/source/i18n/Makefile.in +++ b/icu4c/source/i18n/Makefile.in @@ -101,7 +101,8 @@ sharedbreakiterator.o scientificnumberformatter.o digitgrouping.o \ digitinterval.o digitformatter.o digitaffix.o valueformatter.o \ digitaffixesandpadding.o pluralaffix.o precision.o \ affixpatternparser.o smallintformatter.o decimfmtimpl.o \ -visibledigits.o dayperiodrules.o +visibledigits.o dayperiodrules.o \ +nounit.o ## Header files to install HEADERS = $(srcdir)/unicode/*.h diff --git a/icu4c/source/i18n/measunit.cpp b/icu4c/source/i18n/measunit.cpp index 15497effb99..d1244ad3535 100644 --- a/icu4c/source/i18n/measunit.cpp +++ b/icu4c/source/i18n/measunit.cpp @@ -33,6 +33,7 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(MeasureUnit) // // Start generated code + static const int32_t gOffsets[] = { 0, 2, @@ -49,11 +50,12 @@ static const int32_t gOffsets[] = { 340, 341, 352, - 358, - 363, - 367, - 371, - 396 + 355, + 361, + 366, + 370, + 374, + 399 }; static const int32_t gIndexes[] = { @@ -72,11 +74,12 @@ static const int32_t gIndexes[] = { 79, 80, 91, - 97, - 102, - 106, - 110, - 135 + 94, + 100, + 105, + 109, + 113, + 138 }; // Must be sorted alphabetically. @@ -95,6 +98,7 @@ static const char * const gTypes[] = { "length", "light", "mass", + "none", "power", "pressure", "speed", @@ -456,6 +460,9 @@ static const char * const gSubTypes[] = { "pound", "stone", "ton", + "base", + "percent", + "permille", "gigawatt", "horsepower", "kilowatt", @@ -504,14 +511,14 @@ static const char * const gSubTypes[] = { // Must be sorted by first value and then second value. static int32_t unitPerUnitToSingleUnit[][4] = { - {327, 297, 16, 0}, - {329, 303, 16, 2}, - {331, 297, 16, 3}, - {331, 385, 4, 2}, - {331, 386, 4, 3}, - {346, 383, 3, 1}, - {349, 11, 15, 4}, - {388, 327, 4, 1} + {327, 297, 17, 0}, + {329, 303, 17, 2}, + {331, 297, 17, 3}, + {331, 388, 4, 2}, + {331, 389, 4, 3}, + {346, 386, 3, 1}, + {349, 11, 16, 4}, + {391, 327, 4, 1} }; MeasureUnit *MeasureUnit::createGForce(UErrorCode &status) { @@ -610,14 +617,6 @@ MeasureUnit *MeasureUnit::createMilePerGallonImperial(UErrorCode &status) { return MeasureUnit::create(4, 3, status); } -// MeasureUnit *MeasureUnit::createEast(UErrorCode &status) {...} - -// MeasureUnit *MeasureUnit::createNorth(UErrorCode &status) {...} - -// MeasureUnit *MeasureUnit::createSouth(UErrorCode &status) {...} - -// MeasureUnit *MeasureUnit::createWest(UErrorCode &status) {...} - MeasureUnit *MeasureUnit::createBit(UErrorCode &status) { return MeasureUnit::create(6, 0, status); } @@ -887,179 +886,179 @@ MeasureUnit *MeasureUnit::createTon(UErrorCode &status) { } MeasureUnit *MeasureUnit::createGigawatt(UErrorCode &status) { - return MeasureUnit::create(14, 0, status); -} - -MeasureUnit *MeasureUnit::createHorsepower(UErrorCode &status) { - return MeasureUnit::create(14, 1, status); -} - -MeasureUnit *MeasureUnit::createKilowatt(UErrorCode &status) { - return MeasureUnit::create(14, 2, status); -} - -MeasureUnit *MeasureUnit::createMegawatt(UErrorCode &status) { - return MeasureUnit::create(14, 3, status); -} - -MeasureUnit *MeasureUnit::createMilliwatt(UErrorCode &status) { - return MeasureUnit::create(14, 4, status); -} - -MeasureUnit *MeasureUnit::createWatt(UErrorCode &status) { - return MeasureUnit::create(14, 5, status); -} - -MeasureUnit *MeasureUnit::createHectopascal(UErrorCode &status) { return MeasureUnit::create(15, 0, status); } -MeasureUnit *MeasureUnit::createInchHg(UErrorCode &status) { +MeasureUnit *MeasureUnit::createHorsepower(UErrorCode &status) { return MeasureUnit::create(15, 1, status); } -MeasureUnit *MeasureUnit::createMillibar(UErrorCode &status) { +MeasureUnit *MeasureUnit::createKilowatt(UErrorCode &status) { return MeasureUnit::create(15, 2, status); } -MeasureUnit *MeasureUnit::createMillimeterOfMercury(UErrorCode &status) { +MeasureUnit *MeasureUnit::createMegawatt(UErrorCode &status) { return MeasureUnit::create(15, 3, status); } -MeasureUnit *MeasureUnit::createPoundPerSquareInch(UErrorCode &status) { +MeasureUnit *MeasureUnit::createMilliwatt(UErrorCode &status) { return MeasureUnit::create(15, 4, status); } -MeasureUnit *MeasureUnit::createKilometerPerHour(UErrorCode &status) { +MeasureUnit *MeasureUnit::createWatt(UErrorCode &status) { + return MeasureUnit::create(15, 5, status); +} + +MeasureUnit *MeasureUnit::createHectopascal(UErrorCode &status) { return MeasureUnit::create(16, 0, status); } -MeasureUnit *MeasureUnit::createKnot(UErrorCode &status) { +MeasureUnit *MeasureUnit::createInchHg(UErrorCode &status) { return MeasureUnit::create(16, 1, status); } -MeasureUnit *MeasureUnit::createMeterPerSecond(UErrorCode &status) { +MeasureUnit *MeasureUnit::createMillibar(UErrorCode &status) { return MeasureUnit::create(16, 2, status); } -MeasureUnit *MeasureUnit::createMilePerHour(UErrorCode &status) { +MeasureUnit *MeasureUnit::createMillimeterOfMercury(UErrorCode &status) { return MeasureUnit::create(16, 3, status); } -MeasureUnit *MeasureUnit::createCelsius(UErrorCode &status) { +MeasureUnit *MeasureUnit::createPoundPerSquareInch(UErrorCode &status) { + return MeasureUnit::create(16, 4, status); +} + +MeasureUnit *MeasureUnit::createKilometerPerHour(UErrorCode &status) { return MeasureUnit::create(17, 0, status); } -MeasureUnit *MeasureUnit::createFahrenheit(UErrorCode &status) { +MeasureUnit *MeasureUnit::createKnot(UErrorCode &status) { return MeasureUnit::create(17, 1, status); } -MeasureUnit *MeasureUnit::createGenericTemperature(UErrorCode &status) { +MeasureUnit *MeasureUnit::createMeterPerSecond(UErrorCode &status) { return MeasureUnit::create(17, 2, status); } -MeasureUnit *MeasureUnit::createKelvin(UErrorCode &status) { +MeasureUnit *MeasureUnit::createMilePerHour(UErrorCode &status) { return MeasureUnit::create(17, 3, status); } -MeasureUnit *MeasureUnit::createAcreFoot(UErrorCode &status) { +MeasureUnit *MeasureUnit::createCelsius(UErrorCode &status) { return MeasureUnit::create(18, 0, status); } -MeasureUnit *MeasureUnit::createBushel(UErrorCode &status) { +MeasureUnit *MeasureUnit::createFahrenheit(UErrorCode &status) { return MeasureUnit::create(18, 1, status); } -MeasureUnit *MeasureUnit::createCentiliter(UErrorCode &status) { +MeasureUnit *MeasureUnit::createGenericTemperature(UErrorCode &status) { return MeasureUnit::create(18, 2, status); } -MeasureUnit *MeasureUnit::createCubicCentimeter(UErrorCode &status) { +MeasureUnit *MeasureUnit::createKelvin(UErrorCode &status) { return MeasureUnit::create(18, 3, status); } +MeasureUnit *MeasureUnit::createAcreFoot(UErrorCode &status) { + return MeasureUnit::create(19, 0, status); +} + +MeasureUnit *MeasureUnit::createBushel(UErrorCode &status) { + return MeasureUnit::create(19, 1, status); +} + +MeasureUnit *MeasureUnit::createCentiliter(UErrorCode &status) { + return MeasureUnit::create(19, 2, status); +} + +MeasureUnit *MeasureUnit::createCubicCentimeter(UErrorCode &status) { + return MeasureUnit::create(19, 3, status); +} + MeasureUnit *MeasureUnit::createCubicFoot(UErrorCode &status) { - return MeasureUnit::create(18, 4, status); + return MeasureUnit::create(19, 4, status); } MeasureUnit *MeasureUnit::createCubicInch(UErrorCode &status) { - return MeasureUnit::create(18, 5, status); + return MeasureUnit::create(19, 5, status); } MeasureUnit *MeasureUnit::createCubicKilometer(UErrorCode &status) { - return MeasureUnit::create(18, 6, status); + return MeasureUnit::create(19, 6, status); } MeasureUnit *MeasureUnit::createCubicMeter(UErrorCode &status) { - return MeasureUnit::create(18, 7, status); + return MeasureUnit::create(19, 7, status); } MeasureUnit *MeasureUnit::createCubicMile(UErrorCode &status) { - return MeasureUnit::create(18, 8, status); + return MeasureUnit::create(19, 8, status); } MeasureUnit *MeasureUnit::createCubicYard(UErrorCode &status) { - return MeasureUnit::create(18, 9, status); + return MeasureUnit::create(19, 9, status); } MeasureUnit *MeasureUnit::createCup(UErrorCode &status) { - return MeasureUnit::create(18, 10, status); + return MeasureUnit::create(19, 10, status); } MeasureUnit *MeasureUnit::createCupMetric(UErrorCode &status) { - return MeasureUnit::create(18, 11, status); + return MeasureUnit::create(19, 11, status); } MeasureUnit *MeasureUnit::createDeciliter(UErrorCode &status) { - return MeasureUnit::create(18, 12, status); + return MeasureUnit::create(19, 12, status); } MeasureUnit *MeasureUnit::createFluidOunce(UErrorCode &status) { - return MeasureUnit::create(18, 13, status); + return MeasureUnit::create(19, 13, status); } MeasureUnit *MeasureUnit::createGallon(UErrorCode &status) { - return MeasureUnit::create(18, 14, status); + return MeasureUnit::create(19, 14, status); } MeasureUnit *MeasureUnit::createGallonImperial(UErrorCode &status) { - return MeasureUnit::create(18, 15, status); + return MeasureUnit::create(19, 15, status); } MeasureUnit *MeasureUnit::createHectoliter(UErrorCode &status) { - return MeasureUnit::create(18, 16, status); + return MeasureUnit::create(19, 16, status); } MeasureUnit *MeasureUnit::createLiter(UErrorCode &status) { - return MeasureUnit::create(18, 17, status); + return MeasureUnit::create(19, 17, status); } MeasureUnit *MeasureUnit::createMegaliter(UErrorCode &status) { - return MeasureUnit::create(18, 18, status); + return MeasureUnit::create(19, 18, status); } MeasureUnit *MeasureUnit::createMilliliter(UErrorCode &status) { - return MeasureUnit::create(18, 19, status); + return MeasureUnit::create(19, 19, status); } MeasureUnit *MeasureUnit::createPint(UErrorCode &status) { - return MeasureUnit::create(18, 20, status); + return MeasureUnit::create(19, 20, status); } MeasureUnit *MeasureUnit::createPintMetric(UErrorCode &status) { - return MeasureUnit::create(18, 21, status); + return MeasureUnit::create(19, 21, status); } MeasureUnit *MeasureUnit::createQuart(UErrorCode &status) { - return MeasureUnit::create(18, 22, status); + return MeasureUnit::create(19, 22, status); } MeasureUnit *MeasureUnit::createTablespoon(UErrorCode &status) { - return MeasureUnit::create(18, 23, status); + return MeasureUnit::create(19, 23, status); } MeasureUnit *MeasureUnit::createTeaspoon(UErrorCode &status) { - return MeasureUnit::create(18, 24, status); + return MeasureUnit::create(19, 24, status); } // End generated code @@ -1269,6 +1268,15 @@ void MeasureUnit::initCurrency(const char *isoCurrency) { } } +void MeasureUnit::initNoUnit(const char *subtype) { + int32_t result = binarySearch(gTypes, 0, UPRV_LENGTHOF(gTypes), "none"); + U_ASSERT(result != -1); + fTypeId = result; + result = binarySearch(gSubTypes, gOffsets[fTypeId], gOffsets[fTypeId + 1], subtype); + U_ASSERT(result != -1); + fSubTypeId = result - gOffsets[fTypeId]; +} + void MeasureUnit::setTo(int32_t typeId, int32_t subTypeId) { fTypeId = typeId; fSubTypeId = subTypeId; diff --git a/icu4c/source/i18n/nounit.cpp b/icu4c/source/i18n/nounit.cpp new file mode 100644 index 00000000000..db07387c590 --- /dev/null +++ b/icu4c/source/i18n/nounit.cpp @@ -0,0 +1,42 @@ +// © 2017 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#include "unicode/nounit.h" +#include "uassert.h" + +#if !UCONFIG_NO_FORMATTING + +U_NAMESPACE_BEGIN + +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(NoUnit) + +NoUnit U_EXPORT2 NoUnit::base() { + return NoUnit("base"); +} + +NoUnit U_EXPORT2 NoUnit::percent() { + return NoUnit("percent"); +} + +NoUnit U_EXPORT2 NoUnit::permille() { + return NoUnit("permille"); +} + +NoUnit::NoUnit(const char* subtype) { + initNoUnit(subtype); +} + +NoUnit::NoUnit(const NoUnit& other) : MeasureUnit(other) { +} + +UObject* NoUnit::clone() const { + return new NoUnit(*this); +} + +NoUnit::~NoUnit() { +} + + +U_NAMESPACE_END + +#endif diff --git a/icu4c/source/i18n/ucln_in.h b/icu4c/source/i18n/ucln_in.h index 35a8a23e90c..40a5c36d87a 100644 --- a/icu4c/source/i18n/ucln_in.h +++ b/icu4c/source/i18n/ucln_in.h @@ -26,6 +26,7 @@ as the functions are suppose to be called. It's usually best to have child dependencies called first. */ typedef enum ECleanupI18NType { UCLN_I18N_START = -1, + UCLN_I18N_CURRENCY_SPACING, UCLN_I18N_SPOOF, UCLN_I18N_SPOOFDATA, UCLN_I18N_TRANSLITERATOR, diff --git a/icu4c/source/i18n/unicode/fpositer.h b/icu4c/source/i18n/unicode/fpositer.h index 4ad44f9f104..20b7093a290 100644 --- a/icu4c/source/i18n/unicode/fpositer.h +++ b/icu4c/source/i18n/unicode/fpositer.h @@ -98,9 +98,6 @@ public: */ UBool next(FieldPosition& fp); -private: - friend class FieldPositionIteratorHandler; - /** * Sets the data used by the iterator, and resets the position. * Returns U_ILLEGAL_ARGUMENT_ERROR in status if the data is not valid @@ -108,6 +105,9 @@ private: */ void setData(UVector32 *adopt, UErrorCode& status); +private: + friend class FieldPositionIteratorHandler; + UVector32 *data; int32_t pos; }; diff --git a/icu4c/source/i18n/unicode/measunit.h b/icu4c/source/i18n/unicode/measunit.h index af72449ffa3..2204e987aaf 100644 --- a/icu4c/source/i18n/unicode/measunit.h +++ b/icu4c/source/i18n/unicode/measunit.h @@ -1317,6 +1317,12 @@ class U_I18N_API MeasureUnit: public UObject { */ void initCurrency(const char *isoCurrency); + /** + * For ICU use only. + * @internal + */ + void initNoUnit(const char *subtype); + #endif /* U_HIDE_INTERNAL_API */ private: diff --git a/icu4c/source/i18n/unicode/nounit.h b/icu4c/source/i18n/unicode/nounit.h new file mode 100644 index 00000000000..e743363445c --- /dev/null +++ b/icu4c/source/i18n/unicode/nounit.h @@ -0,0 +1,110 @@ +// © 2017 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html +/* + ******************************************************************************* + * Copyright (C) 2009-2017, International Business Machines Corporation, * + * Google, and others. All Rights Reserved. * + ******************************************************************************* + */ + +#ifndef __NOUNIT_H__ +#define __NOUNIT_H__ + + +/** + * \file + * \brief C++ API: units for percent and permille + */ + + +#include "unicode/measunit.h" + +#if !UCONFIG_NO_FORMATTING + +U_NAMESPACE_BEGIN + +/** + * Dimensionless unit for percent and permille. + * @see NumberFormatter + * @draft ICU 60 + */ +class U_I18N_API NoUnit: public MeasureUnit { +public: + /** + * Returns an instance for the base unit (dimensionless and no scaling). + * + * @return a NoUnit instance + * @draft ICU 60 + */ + static NoUnit U_EXPORT2 base(); + + /** + * Returns an instance for percent, or 1/100 of a base unit. + * + * @return a NoUnit instance + * @draft ICU 60 + */ + static NoUnit U_EXPORT2 percent(); + + /** + * Returns an instance for permille, or 1/1000 of a base unit. + * + * @return a NoUnit instance + * @draft ICU 60 + */ + static NoUnit U_EXPORT2 permille(); + + /** + * Copy operator. + * @draft ICU 60 + */ + NoUnit(const NoUnit& other); + + /** + * Return a polymorphic clone of this object. The result will + * have the same class as returned by getDynamicClassID(). + * @stable ICU 3.0 + */ + virtual UObject* clone() const; + + /** + * Returns a unique class ID for this object POLYMORPHICALLY. + * This method implements a simple form of RTTI used by ICU. + * @return The class ID for this object. All objects of a given + * class have the same class ID. Objects of other classes have + * different class IDs. + * @draft ICU 60 + */ + virtual UClassID getDynamicClassID() const; + + /** + * Returns the class ID for this class. This is used to compare to + * the return value of getDynamicClassID(). + * @return The class ID for all objects of this class. + * @draft ICU 60 + */ + static UClassID U_EXPORT2 getStaticClassID(); + + /** + * Destructor. + * @draft ICU 60 + */ + virtual ~NoUnit(); + +private: + /** + * Constructor + * @internal (private) + */ + NoUnit(const char* subtype); + +}; + + +U_NAMESPACE_END + +#endif /* #if !UCONFIG_NO_FORMATTING */ + +#endif // __NOUNIT_H__ +//eof +//