{ "yocto", UMEASURE_SI_PREFIX_YOCTO },
};
-// FIXME: Get this list from data
+// TODO(ICU-20920): Get this list from data
const char16_t* const gSimpleUnits[] = {
u"one", // note: expected to be index 0
u"100kilometer",
int32_t fMatch;
};
-struct PowerUnit {
+struct SingleUnit {
int8_t power = 1;
UMeasureSIPrefix siPrefix = UMEASURE_SI_PREFIX_ONE;
int32_t simpleUnitIndex = 0;
class CompoundUnit {
public:
- typedef MaybeStackVector<PowerUnit, 3> PowerUnitList;
+ typedef MaybeStackVector<SingleUnit, 3> SingleUnitList;
- void append(PowerUnit&& powerUnit, UErrorCode& status) {
- if (powerUnit.power >= 0) {
- appendImpl(numerator, std::move(powerUnit), status);
+ void append(SingleUnit&& singleUnit, UErrorCode& status) {
+ if (singleUnit.power >= 0) {
+ appendImpl(numerator, std::move(singleUnit), status);
} else {
- appendImpl(denominator, std::move(powerUnit), status);
+ appendImpl(denominator, std::move(singleUnit), status);
}
}
denominator = std::move(temp);
}
- void appendTo(CharString& builder, UErrorCode& status) {
+ void appendTo(CharString& builder, UErrorCode& status) const {
if (numerator.length() == 0) {
builder.append("one", status);
} else {
}
}
- const PowerUnitList& getNumeratorUnits() {
+ const SingleUnitList& getNumeratorUnits() const {
return numerator;
}
- const PowerUnitList& getDenominatorUnits() {
+ const SingleUnitList& getDenominatorUnits() const {
return denominator;
}
+ bool isSingle() const {
+ return numerator.length() + denominator.length() == 1;
+ }
+
private:
- PowerUnitList numerator;
- PowerUnitList denominator;
+ SingleUnitList numerator;
+ SingleUnitList denominator;
- void appendToImpl(const PowerUnitList& unitList, int32_t len, CharString& builder, UErrorCode& status) {
+ void appendToImpl(const SingleUnitList& unitList, int32_t len, CharString& builder, UErrorCode& status) const {
bool first = true;
for (int32_t i = 0; i < len; i++) {
if (first) {
}
}
- void appendImpl(PowerUnitList& unitList, PowerUnit&& powerUnit, UErrorCode& status) {
+ void appendImpl(SingleUnitList& unitList, SingleUnit&& singleUnit, UErrorCode& status) {
// Check that the same simple unit doesn't already exist
for (int32_t i = 0; i < unitList.length(); i++) {
- PowerUnit* candidate = unitList[i];
- if (candidate->simpleUnitIndex == powerUnit.simpleUnitIndex
- && candidate->siPrefix == powerUnit.siPrefix) {
- candidate->power += powerUnit.power;
+ SingleUnit* candidate = unitList[i];
+ if (candidate->simpleUnitIndex == singleUnit.simpleUnitIndex
+ && candidate->siPrefix == singleUnit.siPrefix) {
+ candidate->power += singleUnit.power;
return;
}
}
// Add a new unit
- PowerUnit* destination = unitList.emplaceBack();
+ SingleUnit* destination = unitList.emplaceBack();
if (!destination) {
status = U_MEMORY_ALLOCATION_ERROR;
return;
}
- *destination = std::move(powerUnit);
+ *destination = std::move(singleUnit);
}
};
return fIndex < fSource.length();
}
- PowerUnit getOnlyPowerUnit(UErrorCode& status) {
+ SingleUnit getOnlySingleUnit(UErrorCode& status) {
bool sawPlus;
- PowerUnit retval;
- nextPowerUnit(retval, sawPlus, status);
+ SingleUnit retval;
+ nextSingleUnit(retval, sawPlus, status);
if (U_FAILURE(status)) {
return retval;
}
}
while (hasNext()) {
int32_t previ = fIndex;
- PowerUnit powerUnit;
- nextPowerUnit(powerUnit, sawPlus, status);
+ SingleUnit singleUnit;
+ nextSingleUnit(singleUnit, sawPlus, status);
if (sawPlus) {
fIndex = previ;
break;
}
- result.append(std::move(powerUnit), status);
+ result.append(std::move(singleUnit), status);
}
return;
}
return Token(match);
}
- void nextPowerUnit(PowerUnit& result, bool& sawPlus, UErrorCode& status) {
+ void nextSingleUnit(SingleUnit& result, bool& sawPlus, UErrorCode& status) {
sawPlus = false;
if (U_FAILURE(status)) {
return;
case Token::TYPE_ONE:
// Skip "one" and go to the next unit
- return nextPowerUnit(result, sawPlus, status);
+ return nextSingleUnit(result, sawPlus, status);
case Token::TYPE_SIMPLE_UNIT:
result.simpleUnitIndex = token.getSimpleUnitIndex();
return MeasureUnit(builder.cloneData(status));
}
+UMeasureUnitComplexity MeasureUnit::getComplexity(UErrorCode& status) const {
+ const char* id = getIdentifier();
+ UnitIdentifierParser parser = UnitIdentifierParser::from(id, status);
+ if (U_FAILURE(status)) {
+ // Unrecoverable error
+ return UMEASURE_UNIT_SINGLE;
+ }
+
+ CompoundUnit compoundUnit;
+ parser.nextCompoundUnit(compoundUnit, status);
+ if (compoundUnit.isSingle()) {
+ return UMEASURE_UNIT_SINGLE;
+ } else if (parser.hasNext()) {
+ return UMEASURE_UNIT_SEQUENCE;
+ } else {
+ return UMEASURE_UNIT_COMPOUND;
+ }
+}
+
UMeasureSIPrefix MeasureUnit::getSIPrefix(UErrorCode& status) const {
const char* id = getIdentifier();
- return UnitIdentifierParser::from(id, status).getOnlyPowerUnit(status).siPrefix;
+ return UnitIdentifierParser::from(id, status).getOnlySingleUnit(status).siPrefix;
}
MeasureUnit MeasureUnit::withSIPrefix(UMeasureSIPrefix prefix, UErrorCode& status) const {
const char* id = getIdentifier();
- PowerUnit powerUnit = UnitIdentifierParser::from(id, status).getOnlyPowerUnit(status);
+ SingleUnit singleUnit = UnitIdentifierParser::from(id, status).getOnlySingleUnit(status);
if (U_FAILURE(status)) {
return *this;
}
- powerUnit.siPrefix = prefix;
+ singleUnit.siPrefix = prefix;
CharString builder;
- powerUnit.appendTo(builder, status);
+ singleUnit.appendTo(builder, status);
return MeasureUnit(builder.cloneData(status));
}
int8_t MeasureUnit::getPower(UErrorCode& status) const {
const char* id = getIdentifier();
- return UnitIdentifierParser::from(id, status).getOnlyPowerUnit(status).power;
+ return UnitIdentifierParser::from(id, status).getOnlySingleUnit(status).power;
}
MeasureUnit MeasureUnit::withPower(int8_t power, UErrorCode& status) const {
const char* id = getIdentifier();
- PowerUnit powerUnit = UnitIdentifierParser::from(id, status).getOnlyPowerUnit(status);
+ SingleUnit singleUnit = UnitIdentifierParser::from(id, status).getOnlySingleUnit(status);
if (U_FAILURE(status)) {
return *this;
}
CharString builder;
- powerUnit.power = power;
+ singleUnit.power = power;
if (power < 0) {
builder.append("one-per-", status);
}
- powerUnit.appendTo(builder, status);
+ singleUnit.appendTo(builder, status);
return MeasureUnit(builder.cloneData(status));
}
return MeasureUnit(builder.cloneData(status));
}
-LocalArray<MeasureUnit> MeasureUnit::getSimpleUnits(UErrorCode& status) const {
+LocalArray<MeasureUnit> MeasureUnit::getSingleUnits(UErrorCode& status) const {
const char* id = getIdentifier();
CompoundUnit compoundUnit = UnitIdentifierParser::from(id, status).getOnlyCompoundUnit(status);
if (U_FAILURE(status)) {
return LocalArray<MeasureUnit>::withLength(nullptr, 0);
}
- const CompoundUnit::PowerUnitList& numerator = compoundUnit.getNumeratorUnits();
- const CompoundUnit::PowerUnitList& denominator = compoundUnit.getDenominatorUnits();
+ const CompoundUnit::SingleUnitList& numerator = compoundUnit.getNumeratorUnits();
+ const CompoundUnit::SingleUnitList& denominator = compoundUnit.getDenominatorUnits();
int32_t count = numerator.length() + denominator.length();
MeasureUnit* arr = new MeasureUnit[count];
class StringEnumeration;
+/**
+ * Enumeration for unit complexity. There are three levels:
+ *
+ * - SINGLE: A single unit, optionally with a power and/or SI prefix. Examples: hectare,
+ * square-kilometer, kilojoule, one-per-second.
+ * - COMPOUND: A unit composed of the product of multiple single units. Examples:
+ * meter-per-second, kilowatt-hour, kilogram-meter-per-square-second.
+ * - SEQUENCE: A unit composed of the sum of multiple compound units. Examples: foot+inch,
+ * hour+minute+second, hectare+square-meter.
+ *
+ * The complexity determines which operations are available. For example, you cannot set the power
+ * or SI prefix of a compound unit.
+ *
+ * @draft ICU 67
+ */
+enum UMeasureUnitComplexity {
+ /**
+ * A single unit, like kilojoule.
+ *
+ * @draft ICU 67
+ */
+ UMEASURE_UNIT_SINGLE,
+
+ /**
+ * A compound unit, like meter-per-second.
+ *
+ * @draft ICU 67
+ */
+ UMEASURE_UNIT_COMPOUND,
+
+ /**
+ * A sequence unit, like hour+minute.
+ *
+ * @draft ICU 67
+ */
+ UMEASURE_UNIT_SEQUENCE
+};
+
/**
* Enumeration for SI prefixes, such as "kilo".
*
const char* getIdentifier() const;
/**
- * Creates a MeasureUnit which is this MeasureUnit augmented with the specified SI prefix.
+ * Compute the complexity of the unit. See UMeasureUnitComplexity for more information.
+ *
+ * @param status Set if an error occurs.
+ * @return The unit complexity.
+ * @draft ICU 67
+ */
+ UMeasureUnitComplexity getComplexity(UErrorCode& status) const;
+
+ /**
+ * Creates a MeasureUnit which is this SINGLE unit augmented with the specified SI prefix.
* For example, UMEASURE_SI_PREFIX_KILO for "kilo".
*
* There is sufficient locale data to format all standard SI prefixes.
*
- * This method only works if the MeasureUnit is composed of only one simple unit. An error
- * will be set if called on a MeasureUnit containing multiple units.
+ * NOTE: Only works on SINGLE units. If this is a COMPOUND or SEQUENCE unit, an error will
+ * occur. For more information, see UMeasureUnitComplexity.
*
* @param prefix The SI prefix, from UMeasureSIPrefix.
- * @param status ICU error code
- * @return A new MeasureUnit.
+ * @param status Set if this is not a SINGLE unit or if another error occurs.
+ * @return A new SINGLE unit.
*/
MeasureUnit withSIPrefix(UMeasureSIPrefix prefix, UErrorCode& status) const;
/**
- * Gets the current SI prefix of this MeasureUnit. For example, if the unit has the SI prefix
+ * Gets the current SI prefix of this SINGLE unit. For example, if the unit has the SI prefix
* "kilo", then UMEASURE_SI_PREFIX_KILO is returned.
*
- * If the MeasureUnit is composed of multiple simple units, the SI prefix of the first simple
- * unit is returned. For example, from "centimeter-kilogram-per-second", the SI prefix
- * UMEASURE_SI_PREFIX_CENTI will be returned.
+ * NOTE: Only works on SINGLE units. If this is a COMPOUND or SEQUENCE unit, an error will
+ * occur. For more information, see UMeasureUnitComplexity.
*
- * @return The SI prefix of the first simple unit, from UMeasureSIPrefix.
+ * @param status Set if this is not a SINGLE unit or if another error occurs.
+ * @return The SI prefix of this SINGLE unit, from UMeasureSIPrefix.
*/
UMeasureSIPrefix getSIPrefix(UErrorCode& status) const;
/**
- * Creates a MeasureUnit which is this MeasureUnit augmented with the specified power. For
+ * Creates a MeasureUnit which is this SINGLE unit augmented with the specified power. For
* example, if power is 2, the unit will be squared.
*
- * This method only works if the MeasureUnit is composed of only one simple unit. An error
- * will be set if called on a MeasureUnit containing multiple units.
+ * NOTE: Only works on SINGLE units. If this is a COMPOUND or SEQUENCE unit, an error will
+ * occur. For more information, see UMeasureUnitComplexity.
*
* @param power The power.
- * @param status ICU error code
- * @return A new MeasureUnit.
+ * @param status Set if this is not a SINGLE unit or if another error occurs.
+ * @return A new SINGLE unit.
*/
MeasureUnit withPower(int8_t power, UErrorCode& status) const;
/**
* Gets the power of this MeasureUnit. For example, if the unit is square, then 2 is returned.
*
- * If the MeasureUnit is composed of multiple simple units, the power of the first simple unit
- * is returned. For example, from "cubic-meter-per-square-second", 3 is returned.
+ * NOTE: Only works on SINGLE units. If this is a COMPOUND or SEQUENCE unit, an error will
+ * occur. For more information, see UMeasureUnitComplexity.
*
- * @return The power of the first simple unit.
+ * @param status Set if this is not a SINGLE unit or if another error occurs.
+ * @return The power of this simple unit.
*/
int8_t getPower(UErrorCode& status) const;
/**
- * Gets the reciprocal of the unit, with the numerator and denominator flipped.
+ * Gets the reciprocal of this MeasureUnit, with the numerator and denominator flipped.
*
* For example, if the receiver is "meter-per-second", the unit "second-per-meter" is returned.
*
+ * NOTE: Only works on SINGLE and COMPOUND units. If this is a SEQUENCE unit, an error will
+ * occur. For more information, see UMeasureUnitComplexity.
+ *
+ * @param status Set if this is a SEQUENCE unit or if another error occurs.
* @return The reciprocal of the target unit.
*/
MeasureUnit reciprocal(UErrorCode& status) const;
* For example, if the receiver is "kilowatt" and the argument is "hour-per-day", then the
* unit "kilowatt-hour-per-day" is returned.
*
+ * NOTE: Only works on SINGLE and COMPOUND units. If either unit (receivee and argument) is a
+ * SEQUENCE unit, an error will occur. For more information, see UMeasureUnitComplexity.
+ *
+ * @param status Set if this or other is a SEQUENCE unit or if another error occurs.
* @return The product of the target unit with the provided unit.
*/
MeasureUnit product(const MeasureUnit& other, UErrorCode& status) const;
/**
- * Gets the number of constituent simple units.
- *
- * For example, if the receiver is "meter-per-square-second", then 2 is returned, since there
- * are two simple units: "meter" and "second".
- *
- * @return The number of constituent units.
- */
- size_t getSimpleUnitCount(UErrorCode& status) const;
-
- LocalArray<MeasureUnit> getSimpleUnits(UErrorCode& status) const;
-
- LocalArray<MeasureUnit> getSequenceUnits(UErrorCode& status) const;
-
- /**
- * Gets the constituent unit at the given index.
- *
- * For example, to loop over all simple units:
- *
- * <pre>
- * MeasureUnit unit(u"meter-per-square-second");
- * for (size_t i = 0; i < unit.getSimpleUnitCount(); i++) {
- * std::cout << unit.simpleUnitAt(i).toString() << std::endl;
- * }
- * </pre>
- *
- * Expected output: meter, one-per-square-second
- *
- * @param index Zero-based index. If out of range, the dimensionless unit is returned.
- * @return The constituent simple unit at the specified position.
- */
- MeasureUnit simpleUnitAt(size_t index, UErrorCode& status) const;
-
- /**
- * Composes this unit with a super unit.
- *
- * A super unit, used for formatting only, should be a larger unit sharing the same dimension.
- * For example, if the current unit is "inch", a super unit could be "foot", in order to
- * render 71 inches as "5 feet, 11 inches". If the super unit is invalid, an error will occur
- * during formatting.
+ * Gets the list of single units contained within a compound unit.
*
- * A unit can have multiple super units; for example, "second" could have both "minute" and
- * "hour" as super units.
- *
- * Super units are ignored and left untouched in most other methods, such as withSIPrefix,
- * withPower, and reciprocal.
+ * For example, given "meter-kilogram-per-second", three units will be returned: "meter",
+ * "kilogram", and "one-per-second".
*
- * @param other The super unit to compose with the target unit.
- * @return The composition of the given super unit with this unit.
- */
- MeasureUnit withSuperUnit(const MeasureUnit& other, UErrorCode& status) const;
-
- /**
- * Gets the number of super units in the receiver.
+ * If this is a SINGLE unit, an array of length 1 will be returned.
*
- * For example, "foot+inch" has one super unit.
+ * NOTE: Only works on SINGLE and COMPOUND units. If this is a SEQUENCE unit, an error will
+ * occur. For more information, see UMeasureUnitComplexity.
*
- * @return The number of super units.
+ * @param status Set if this is a SEQUENCE unit or if another error occurs.
+ * @return An array of single units, owned by the caller.
*/
- size_t getSuperUnitCount(UErrorCode& status) const;
+ LocalArray<MeasureUnit> getSingleUnits(UErrorCode& status) const;
/**
- * Gets the super unit at the given index.
+ * Gets the list of compound units contained within a sequence unit.
*
- * For example, to loop over all super units:
- *
- * <pre>
- * MeasureUnit unit(u"hour+minute+second");
- * for (size_t i = 0; i < unit.getSuperUnitCount(); i++) {
- * std::cout << unit.superUnitAt(i).toCoreUnitIdentifier() << std::endl;
- * }
- * </pre>
+ * For example, given "hour+minute+second", three units will be returned: "hour", "minute",
+ * and "second".
*
- * Expected output: hour, minute
+ * If this is a SINGLE or COMPOUND unit, an array of length 1 will be returned.
*
- * @return The super unit at the specified position.
+ * @param status Set of an error occurs.
+ * @return An array of compound units, owned by the caller.
*/
- MeasureUnit superUnitAt(size_t index, UErrorCode& status) const;
+ LocalArray<MeasureUnit> getCompoundUnits(UErrorCode& status) const;
/**
* getAvailable gets all of the available units.
NumberFormat::EAlignmentFields field,
int32_t start,
int32_t end);
- void verifyPowerUnit(
+ void verifySingleUnit(
const MeasureUnit& unit,
UMeasureSIPrefix siPrefix,
int8_t power,
MeasureUnit centimeter2 = meter.withSIPrefix(UMEASURE_SI_PREFIX_CENTI, status);
MeasureUnit cubicDecimeter = cubicMeter.withSIPrefix(UMEASURE_SI_PREFIX_DECI, status);
- verifyPowerUnit(kilometer, UMEASURE_SI_PREFIX_KILO, 1, "kilometer");
- verifyPowerUnit(meter, UMEASURE_SI_PREFIX_ONE, 1, "meter");
- verifyPowerUnit(centimeter1, UMEASURE_SI_PREFIX_CENTI, 1, "centimeter");
- verifyPowerUnit(centimeter2, UMEASURE_SI_PREFIX_CENTI, 1, "centimeter");
- verifyPowerUnit(cubicDecimeter, UMEASURE_SI_PREFIX_DECI, 3, "cubic-decimeter");
+ verifySingleUnit(kilometer, UMEASURE_SI_PREFIX_KILO, 1, "kilometer");
+ verifySingleUnit(meter, UMEASURE_SI_PREFIX_ONE, 1, "meter");
+ verifySingleUnit(centimeter1, UMEASURE_SI_PREFIX_CENTI, 1, "centimeter");
+ verifySingleUnit(centimeter2, UMEASURE_SI_PREFIX_CENTI, 1, "centimeter");
+ verifySingleUnit(cubicDecimeter, UMEASURE_SI_PREFIX_DECI, 3, "cubic-decimeter");
assertTrue("centimeter equality", centimeter1 == centimeter2);
assertTrue("kilometer inequality", centimeter1 != kilometer);
MeasureUnit quarticKilometer = kilometer.withPower(4, status);
MeasureUnit overQuarticKilometer1 = kilometer.withPower(-4, status);
- verifyPowerUnit(squareMeter, UMEASURE_SI_PREFIX_ONE, 2, "square-meter");
- verifyPowerUnit(overCubicCentimeter, UMEASURE_SI_PREFIX_CENTI, -3, "one-per-cubic-centimeter");
- verifyPowerUnit(quarticKilometer, UMEASURE_SI_PREFIX_KILO, 4, "p4-kilometer");
- verifyPowerUnit(overQuarticKilometer1, UMEASURE_SI_PREFIX_KILO, -4, "one-per-p4-kilometer");
+ verifySingleUnit(squareMeter, UMEASURE_SI_PREFIX_ONE, 2, "square-meter");
+ verifySingleUnit(overCubicCentimeter, UMEASURE_SI_PREFIX_CENTI, -3, "one-per-cubic-centimeter");
+ verifySingleUnit(quarticKilometer, UMEASURE_SI_PREFIX_KILO, 4, "p4-kilometer");
+ verifySingleUnit(overQuarticKilometer1, UMEASURE_SI_PREFIX_KILO, -4, "one-per-p4-kilometer");
assertTrue("power inequality", quarticKilometer != overQuarticKilometer1);
.product(kilometer, status)
.reciprocal(status);
- verifyPowerUnit(overQuarticKilometer2, UMEASURE_SI_PREFIX_KILO, -4, "one-per-p4-kilometer");
- verifyPowerUnit(overQuarticKilometer3, UMEASURE_SI_PREFIX_KILO, -4, "one-per-p4-kilometer");
+ verifySingleUnit(overQuarticKilometer2, UMEASURE_SI_PREFIX_KILO, -4, "one-per-p4-kilometer");
+ verifySingleUnit(overQuarticKilometer3, UMEASURE_SI_PREFIX_KILO, -4, "one-per-p4-kilometer");
assertTrue("reciprocal equality", overQuarticKilometer1 == overQuarticKilometer2);
assertTrue("reciprocal equality", overQuarticKilometer1 == overQuarticKilometer3);
MeasureUnit secondCentimeter = kiloSquareSecond.product(meter.withSIPrefix(UMEASURE_SI_PREFIX_CENTI, status), status);
MeasureUnit secondCentimeterPerKilometer = secondCentimeter.product(kilometer.reciprocal(status), status);
- verifyPowerUnit(kiloSquareSecond, UMEASURE_SI_PREFIX_KILO, 2, "square-kilosecond");
+ verifySingleUnit(kiloSquareSecond, UMEASURE_SI_PREFIX_KILO, 2, "square-kilosecond");
const char* meterSecondSub[] = {"meter", "square-kilosecond"};
verifyCompoundUnit(meterSecond, "meter-square-kilosecond",
meterSecondSub, UPRV_LENGTHOF(meterSecondSub));
}
}
-void MeasureFormatTest::verifyPowerUnit(
+void MeasureFormatTest::verifySingleUnit(
const MeasureUnit& unit,
UMeasureSIPrefix siPrefix,
int8_t power,
const char* identifier) {
- IcuTestErrorCode status(*this, "verifyPowerUnit");
+ IcuTestErrorCode status(*this, "verifySingleUnit");
UnicodeString uid(identifier, -1, US_INV);
assertEquals(uid + ": SI prefix",
siPrefix,
assertTrue(uid + ": Constructor",
unit == MeasureUnit::forIdentifier(identifier, status));
status.errIfFailureAndReset("%s: Constructor", identifier);
+ assertEquals(uid + ": Complexity",
+ UMEASURE_UNIT_SINGLE,
+ unit.getComplexity(status));
+ status.errIfFailureAndReset("%s: Complexity", identifier);
}
void MeasureFormatTest::verifyCompoundUnit(
assertTrue(uid + ": Constructor",
unit == MeasureUnit::forIdentifier(identifier, status));
status.errIfFailureAndReset("%s: Constructor", identifier);
+ assertEquals(uid + ": Complexity",
+ UMEASURE_UNIT_COMPOUND,
+ unit.getComplexity(status));
+ status.errIfFailureAndReset("%s: Complexity", identifier);
- LocalArray<MeasureUnit> subUnits = unit.getSimpleUnits(status);
+ LocalArray<MeasureUnit> subUnits = unit.getSingleUnits(status);
assertEquals(uid + ": Length", subIdentifierCount, subUnits.length());
for (int32_t i = 0;; i++) {
if (i >= subIdentifierCount || i >= subUnits.length()) break;
assertEquals(uid + ": Sub-unit #" + Int64ToUnicodeString(i),
subIdentifiers[i],
subUnits[i].getIdentifier());
+ assertEquals(uid + ": Sub-unit Complexity",
+ UMEASURE_UNIT_SINGLE,
+ subUnits[i].getComplexity(status));
}
}