ICU-21021 Changing MeasureUnit::splitToSingleUnits to return std::pair

This commit is contained in:
Shane F. Carr 2020-09-14 20:38:32 -05:00
parent b41f12065f
commit 5a35a31e9a
5 changed files with 38 additions and 24 deletions

View file

@ -908,7 +908,7 @@ MeasureUnit MeasureUnit::product(const MeasureUnit& other, UErrorCode& status) c
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();

View file

@ -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 @@ void MixedUnitLongNameHandler::forMeasureUnit(const Locale &loc, const MeasureUn
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;

View file

@ -94,14 +94,14 @@ void mixedMeasuresToMicros(const MaybeStackVector<Measure> &measures, DecimalQua
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.

View file

@ -445,7 +445,7 @@ class U_I18N_API MeasureUnit: public UObject {
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 @@ class U_I18N_API MeasureUnit: public UObject {
*
* 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 @@ private:
*/
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

View file

@ -3933,8 +3933,8 @@ void MeasureFormatTest::TestDimensionlessBehaviour() {
// 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 @@ void MeasureFormatTest::TestDimensionlessBehaviour() {
// 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 @@ void MeasureFormatTest::verifyCompoundUnit(
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 @@ void MeasureFormatTest::verifyMixedUnit(
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;