#include "decNumber.h"
#include "digitlst.h"
#include "fmtableimp.h"
+#include "number_decimalquantity.h"
// *****************************************************************************
// class Formattable
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Formattable)
+using number::impl::DecimalQuantity;
+
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
fType = kLong;
fDecimalStr = NULL;
fDecimalNum = NULL;
+ fDecimalQuantity = NULL;
fBogus.setToBogus();
}
if (source.fDecimalNum != NULL) {
fDecimalNum = new DigitList(*source.fDecimalNum); // TODO: use internal digit list
}
+ if (source.fDecimalQuantity != NULL) {
+ fDecimalQuantity = new DecimalQuantity(*source.fDecimalQuantity);
+ }
if (source.fDecimalStr != NULL) {
fDecimalStr = new CharString(*source.fDecimalStr, status);
if (U_FAILURE(status)) {
fDecimalNum->~DigitList(); // destruct, don't deallocate
}
fDecimalNum = NULL;
+
+ delete fDecimalQuantity;
+ fDecimalQuantity = NULL;
}
Formattable *
}
}
+ if (fDecimalQuantity == NULL) {
+ // No decimal number for the formattable yet...
+ LocalPointer<DecimalQuantity> dq(new DecimalQuantity(), status);
+ if (U_FAILURE(status)) { return nullptr; }
+ populateDecimalQuantity(*dq, status);
+ if (U_FAILURE(status)) { return nullptr; }
+ fDecimalQuantity = dq.orphan();
+ }
+
fDecimalStr = new CharString;
if (fDecimalStr == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
return fDecimalStr;
}
+void
+Formattable::populateDecimalQuantity(number::impl::DecimalQuantity& output, UErrorCode& status) const {
+ if (fDecimalQuantity != nullptr) {
+ output = *fDecimalQuantity;
+ return;
+ }
+
+ switch (fType) {
+ case kDouble:
+ output.setToDouble(this->getDouble());
+ output.roundToInfinity();
+ break;
+ case kLong:
+ output.setToInt(this->getLong());
+ break;
+ case kInt64:
+ output.setToLong(this->getInt64());
+ break;
+ default:
+ // The formattable's value is not a numeric type.
+ status = U_INVALID_STATE_ERROR;
+ }
+}
DigitList *
Formattable::getInternalDigitList() {
}
}
+// ---------------------------------------
+void
+Formattable::adoptDecimalQuantity(DecimalQuantity *dq) {
+ if (fDecimalQuantity != NULL) {
+ delete fDecimalQuantity;
+ }
+ fDecimalQuantity = dq;
+ if (dq == NULL) { // allow adoptDigitList(NULL) to clear
+ return;
+ }
+
+ // Set the value into the Union of simple type values.
+ // Cannot use the set() functions because they would delete the fDecimalNum value.
+ if (fDecimalQuantity->fitsInLong()) {
+ fValue.fInt64 = fDecimalQuantity->toLong();
+ if (fValue.fInt64 <= INT32_MAX && fValue.fInt64 >= INT32_MIN) {
+ fType = kLong;
+ } else {
+ fType = kInt64;
+ }
+ } else {
+ fType = kDouble;
+ fValue.fDouble = fDecimalQuantity->toDouble();
+ }
+}
+
// ---------------------------------------
void
}
adoptDigitList(dnum);
+ auto* dq = new DecimalQuantity();
+ dq->setToDecNumber(numberString, status);
+ adoptDecimalQuantity(dq);
+
// Note that we do not hang on to the caller's input string.
// If we are asked for the string, we will regenerate one from fDecimalNum.
}