ICU-21349 Delete MeasureUnitImpl copy constructor, drop an indirection
diff --git a/icu4c/source/i18n/measunit_extra.cpp b/icu4c/source/i18n/measunit_extra.cpp
index 676ff88..6c82ffb 100644
--- a/icu4c/source/i18n/measunit_extra.cpp
+++ b/icu4c/source/i18n/measunit_extra.cpp
@@ -955,10 +955,6 @@
return gSimpleUnitCategories[index];
}
-MeasureUnitImpl::MeasureUnitImpl(const MeasureUnitImpl &other, UErrorCode &status) {
- *this = other.copy(status);
-}
-
MeasureUnitImpl::MeasureUnitImpl(const SingleUnitImpl &singleUnit, UErrorCode &status) {
this->appendSingleUnit(singleUnit, status);
}
@@ -1040,12 +1036,12 @@
MaybeStackVector<MeasureUnitImplWithIndex> result;
if (this->complexity != UMeasureUnitComplexity::UMEASURE_UNIT_MIXED) {
- result.emplaceBackAndCheckErrorCode(status, 0, new MeasureUnitImpl(*this, status));
+ result.emplaceBackAndCheckErrorCode(status, 0, *this, status);
return result;
}
for (int32_t i = 0; i < singleUnits.length(); ++i) {
- result.emplaceBackAndCheckErrorCode(status, i, new MeasureUnitImpl(*singleUnits[i], status));
+ result.emplaceBackAndCheckErrorCode(status, i, *singleUnits[i], status);
if (U_FAILURE(status)) {
return result;
}
diff --git a/icu4c/source/i18n/measunit_impl.h b/icu4c/source/i18n/measunit_impl.h
index 6c5a5ac..f88d900 100644
--- a/icu4c/source/i18n/measunit_impl.h
+++ b/icu4c/source/i18n/measunit_impl.h
@@ -39,14 +39,6 @@
static const char16_t kDefaultCurrency[] = u"XXX";
static const char kDefaultCurrency8[] = "XXX";
-struct U_I18N_API MeasureUnitImplWithIndex : public UMemory {
- const int32_t index;
- LocalPointer<MeasureUnitImpl> unitImpl;
- // Takes ownership of unitImpl.
- MeasureUnitImplWithIndex(int32_t index, MeasureUnitImpl *unitImpl)
- : index(index), unitImpl(unitImpl) {}
-};
-
/**
* Looks up the "unitQuantity" (aka "type" or "category") of a base unit
* identifier. The category is returned via `result`, which must initially be
@@ -192,6 +184,9 @@
int32_t dimensionality = 1;
};
+// Forward declaration
+struct MeasureUnitImplWithIndex;
+
// Export explicit template instantiations of MaybeStackArray, MemoryPool and
// MaybeStackVector. This is required when building DLLs for Windows. (See
// datefmt.h, collationiterator.h, erarules.h and others for similar examples.)
@@ -212,7 +207,8 @@
public:
MeasureUnitImpl() = default;
MeasureUnitImpl(MeasureUnitImpl &&other) = default;
- MeasureUnitImpl(const MeasureUnitImpl &other, UErrorCode &status);
+ // No copy constructor, use MeasureUnitImpl::copy() to make it explicit.
+ MeasureUnitImpl(const MeasureUnitImpl &other, UErrorCode &status) = delete;
MeasureUnitImpl(const SingleUnitImpl &singleUnit, UErrorCode &status);
MeasureUnitImpl &operator=(MeasureUnitImpl &&other) noexcept = default;
@@ -322,6 +318,18 @@
friend class number::impl::LongNameHandler;
};
+struct U_I18N_API MeasureUnitImplWithIndex : public UMemory {
+ const int32_t index;
+ MeasureUnitImpl unitImpl;
+ // Makes a copy of unitImpl.
+ MeasureUnitImplWithIndex(int32_t index, const MeasureUnitImpl &unitImpl, UErrorCode &status)
+ : index(index), unitImpl(unitImpl.copy(status)) {
+ }
+ MeasureUnitImplWithIndex(int32_t index, const SingleUnitImpl &singleUnitImpl, UErrorCode &status)
+ : index(index), unitImpl(MeasureUnitImpl(singleUnitImpl, status)) {
+ }
+};
+
U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/icu4c/source/i18n/units_complexconverter.cpp b/icu4c/source/i18n/units_complexconverter.cpp
index 8ecb1b3..89a60e4 100644
--- a/icu4c/source/i18n/units_complexconverter.cpp
+++ b/icu4c/source/i18n/units_complexconverter.cpp
@@ -31,11 +31,11 @@
U_ASSERT(units_.length() != 0);
// Just borrowing a pointer to the instance
- MeasureUnitImpl *biggestUnit = units_[0]->unitImpl.getAlias();
+ MeasureUnitImpl *biggestUnit = &units_[0]->unitImpl;
for (int32_t i = 1; i < units_.length(); i++) {
- if (UnitsConverter::compareTwoUnits(*units_[i]->unitImpl, *biggestUnit, ratesInfo, status) > 0 &&
+ if (UnitsConverter::compareTwoUnits(units_[i]->unitImpl, *biggestUnit, ratesInfo, status) > 0 &&
U_SUCCESS(status)) {
- biggestUnit = units_[i]->unitImpl.getAlias();
+ biggestUnit = &units_[i]->unitImpl;
}
if (U_FAILURE(status)) {
@@ -85,10 +85,10 @@
const auto *rightPointer = static_cast<const MeasureUnitImplWithIndex *const *>(right);
// Multiply by -1 to sort in descending order
- return (-1) * UnitsConverter::compareTwoUnits(*((**leftPointer).unitImpl) /* left unit*/, //
- *((**rightPointer).unitImpl) /* right unit */, //
- *static_cast<const ConversionRates *>(context), //
- status);
+ return (-1) * UnitsConverter::compareTwoUnits((**leftPointer).unitImpl, //
+ (**rightPointer).unitImpl, //
+ *static_cast<const ConversionRates *>(context), //
+ status);
};
uprv_sortArray(units_.getAlias(), //
@@ -116,11 +116,11 @@
// 3. then, the final result will be (6 feet and 6.74016 inches)
for (int i = 0, n = units_.length(); i < n; i++) {
if (i == 0) { // first element
- unitsConverters_.emplaceBackAndCheckErrorCode(status, inputUnit, *(units_[i]->unitImpl),
- ratesInfo, status);
+ unitsConverters_.emplaceBackAndCheckErrorCode(status, inputUnit, units_[i]->unitImpl,
+ ratesInfo, status);
} else {
- unitsConverters_.emplaceBackAndCheckErrorCode(status, *(units_[i - 1]->unitImpl),
- *(units_[i]->unitImpl), ratesInfo, status);
+ unitsConverters_.emplaceBackAndCheckErrorCode(status, units_[i - 1]->unitImpl,
+ units_[i]->unitImpl, ratesInfo, status);
}
if (U_FAILURE(status)) {
@@ -200,12 +200,12 @@
if (i < n - 1) {
Formattable formattableQuantity(intValues[i] * sign);
// Measure takes ownership of the MeasureUnit*
- MeasureUnit *type = new MeasureUnit(units_[i]->unitImpl->copy(status).build(status));
+ MeasureUnit *type = new MeasureUnit(units_[i]->unitImpl.copy(status).build(status));
tmpResult[units_[i]->index] = new Measure(formattableQuantity, type, status);
} else { // LAST ELEMENT
Formattable formattableQuantity(quantity * sign);
// Measure takes ownership of the MeasureUnit*
- MeasureUnit *type = new MeasureUnit(units_[i]->unitImpl->copy(status).build(status));
+ MeasureUnit *type = new MeasureUnit(units_[i]->unitImpl.copy(status).build(status));
tmpResult[units_[i]->index] = new Measure(formattableQuantity, type, status);
}
}