ICU-21021 Changing MeasureUnit::splitToSingleUnits to return std::pair
diff --git a/icu4c/source/i18n/measunit_extra.cpp b/icu4c/source/i18n/measunit_extra.cpp
index 83a4de8..2eb3f06 100644
--- a/icu4c/source/i18n/measunit_extra.cpp
+++ b/icu4c/source/i18n/measunit_extra.cpp
@@ -908,7 +908,7 @@
return std::move(impl).build(status);
}
-LocalArray<MeasureUnit> MeasureUnit::splitToSingleUnits(int32_t& outCount, UErrorCode& status) const {
+LocalArray<MeasureUnit> MeasureUnit::splitToSingleUnitsImpl(int32_t& outCount, UErrorCode& status) const {
MeasureUnitImpl temp;
const MeasureUnitImpl& impl = MeasureUnitImpl::forMeasureUnit(*this, temp, status);
outCount = impl.units.length();
diff --git a/icu4c/source/i18n/number_longnames.cpp b/icu4c/source/i18n/number_longnames.cpp
index 691fb13..953f12f 100644
--- a/icu4c/source/i18n/number_longnames.cpp
+++ b/icu4c/source/i18n/number_longnames.cpp
@@ -10,6 +10,7 @@
#include "ureslocs.h"
#include "charstr.h"
#include "uresimp.h"
+#include "measunit_impl.h"
#include "number_longnames.h"
#include "number_microprops.h"
#include <algorithm>
@@ -410,13 +411,14 @@
U_ASSERT(mixedUnit.getComplexity(status) == UMEASURE_UNIT_MIXED);
U_ASSERT(fillIn != nullptr);
- LocalArray<MeasureUnit> individualUnits =
- mixedUnit.splitToSingleUnits(fillIn->fMixedUnitCount, status);
+ MeasureUnitImpl temp;
+ const MeasureUnitImpl& impl = MeasureUnitImpl::forMeasureUnit(mixedUnit, temp, status);
+ fillIn->fMixedUnitCount = impl.units.length();
fillIn->fMixedUnitData.adoptInstead(new UnicodeString[fillIn->fMixedUnitCount * ARRAY_LENGTH]);
for (int32_t i = 0; i < fillIn->fMixedUnitCount; i++) {
// Grab data for each of the components.
UnicodeString *unitData = &fillIn->fMixedUnitData[i * ARRAY_LENGTH];
- getMeasureData(loc, individualUnits[i], width, unitData, status);
+ getMeasureData(loc, impl.units[i]->build(status), width, unitData, status);
}
UListFormatterWidth listWidth = ULISTFMT_WIDTH_SHORT;
diff --git a/icu4c/source/i18n/number_usageprefs.cpp b/icu4c/source/i18n/number_usageprefs.cpp
index cd426f4..9a1de60 100644
--- a/icu4c/source/i18n/number_usageprefs.cpp
+++ b/icu4c/source/i18n/number_usageprefs.cpp
@@ -94,14 +94,14 @@
U_ASSERT(micros->outputUnit.getComplexity(status) == UMEASURE_UNIT_MIXED);
U_ASSERT(U_SUCCESS(status));
// Check that we received measurements with the expected MeasureUnits:
- int32_t singleUnitsCount;
- LocalArray<MeasureUnit> singleUnits =
- micros->outputUnit.splitToSingleUnits(singleUnitsCount, status);
+ MeasureUnitImpl temp;
+ const MeasureUnitImpl& impl = MeasureUnitImpl::forMeasureUnit(micros->outputUnit, temp, status);
U_ASSERT(U_SUCCESS(status));
- U_ASSERT(measures.length() == singleUnitsCount);
+ U_ASSERT(measures.length() == impl.units.length());
for (int32_t i = 0; i < measures.length(); i++) {
- U_ASSERT(measures[i]->getUnit() == singleUnits[i]);
+ U_ASSERT(measures[i]->getUnit() == impl.units[i]->build(status));
}
+ (void)impl;
#endif
// Mixed units: except for the last value, we pass all values to the
// LongNameHandler via micros->mixedMeasures.
diff --git a/icu4c/source/i18n/unicode/measunit.h b/icu4c/source/i18n/unicode/measunit.h
index faa7aef..57d1e71 100644
--- a/icu4c/source/i18n/unicode/measunit.h
+++ b/icu4c/source/i18n/unicode/measunit.h
@@ -445,7 +445,7 @@
MeasureUnit product(const MeasureUnit& other, UErrorCode& status) const;
#endif // U_HIDE_DRAFT_API
-#ifndef U_HIDE_INTERNAL_API
+#ifndef U_HIDE_DRAFT_API
/**
* Gets the list of SINGLE units contained within a MIXED of COMPOUND unit.
*
@@ -457,15 +457,12 @@
*
* If this is a SINGLE unit, an array of length 1 will be returned.
*
- * TODO(ICU-21021): Finalize this API and propose it as draft.
- *
- * @param outCount The number of elements in the return array.
* @param status Set if an error occurs.
- * @return An array of single units, owned by the caller.
- * @internal ICU 67 Technical Preview
+ * @return A pair with the list of units as a LocalArray and the number of units in the list.
+ * @draft ICU 68
*/
- LocalArray<MeasureUnit> splitToSingleUnits(int32_t& outCount, UErrorCode& status) const;
-#endif // U_HIDE_INTERNAL_API
+ inline std::pair<LocalArray<MeasureUnit>, int32_t> splitToSingleUnits(UErrorCode& status) const;
+#endif // U_HIDE_DRAFT_API
/**
* getAvailable gets all of the available units.
@@ -3576,9 +3573,21 @@
*/
static bool findBySubType(StringPiece subType, MeasureUnit* output);
+ /** Internal version of public API */
+ LocalArray<MeasureUnit> splitToSingleUnitsImpl(int32_t& outCount, UErrorCode& status) const;
+
friend struct MeasureUnitImpl;
};
+#ifndef U_HIDE_DRAFT_API // @draft ICU 68
+inline std::pair<LocalArray<MeasureUnit>, int32_t>
+MeasureUnit::splitToSingleUnits(UErrorCode& status) const {
+ int32_t length;
+ auto array = splitToSingleUnitsImpl(length, status);
+ return std::make_pair(std::move(array), length);
+}
+#endif // U_HIDE_DRAFT_API
+
U_NAMESPACE_END
#endif // !UNCONFIG_NO_FORMATTING
diff --git a/icu4c/source/test/intltest/measfmttest.cpp b/icu4c/source/test/intltest/measfmttest.cpp
index fac681e..8690b54 100644
--- a/icu4c/source/test/intltest/measfmttest.cpp
+++ b/icu4c/source/test/intltest/measfmttest.cpp
@@ -3933,8 +3933,8 @@
// Parser::from("") to be called:
// splitToSingleUnits
- int32_t count;
- LocalArray<MeasureUnit> singles = dimensionless.splitToSingleUnits(count, status);
+ auto pair = dimensionless.splitToSingleUnits(status);
+ int32_t count = pair.second;
status.errIfFailureAndReset("dimensionless.splitToSingleUnits(...)");
assertEquals("no singles in dimensionless", 0, count);
@@ -3952,7 +3952,8 @@
// dimensionless.withSIPrefix()
modified = dimensionless.withSIPrefix(UMEASURE_SI_PREFIX_KILO, status);
status.errIfFailureAndReset("dimensionless.withSIPrefix(...)");
- singles = modified.splitToSingleUnits(count, status);
+ pair = dimensionless.splitToSingleUnits(status);
+ count = pair.second;
assertEquals("no singles in modified", 0, count);
siPrefix = modified.getSIPrefix(status);
status.errIfFailureAndReset("modified.getSIPrefix(...)");
@@ -4154,8 +4155,9 @@
unit.getComplexity(status));
status.errIfFailureAndReset("%s: Complexity", identifier);
- int32_t length;
- LocalArray<MeasureUnit> subUnits = unit.splitToSingleUnits(length, status);
+ auto pair = unit.splitToSingleUnits(status);
+ const LocalArray<MeasureUnit>& subUnits = pair.first;
+ int32_t length = pair.second;
assertEquals(uid + ": Length", subIdentifierCount, length);
for (int32_t i = 0;; i++) {
if (i >= subIdentifierCount || i >= length) break;
@@ -4187,8 +4189,9 @@
unit.getComplexity(status));
status.errIfFailureAndReset("%s: Complexity", identifier);
- int32_t length;
- LocalArray<MeasureUnit> subUnits = unit.splitToSingleUnits(length, status);
+ auto pair = unit.splitToSingleUnits(status);
+ const LocalArray<MeasureUnit>& subUnits = pair.first;
+ int32_t length = pair.second;
assertEquals(uid + ": Length", subIdentifierCount, length);
for (int32_t i = 0;; i++) {
if (i >= subIdentifierCount || i >= length) break;