Formattable Formattable::forDecimal(std::string_view number, UErrorCode &status) {
Formattable f; // The relevant overload of the StringPiece constructor // casts the string length to int32_t, so we have to check // that the length makes sense if (number.size() > INT_MAX) {
status = U_ILLEGAL_ARGUMENT_ERROR;
} else {
f.contents = icu::Formattable(StringPiece(number), status);
} return f;
}
UFormattableType Formattable::getType() const { if (std::holds_alternative<double>(contents)) { return holdsDate ? UFMT_DATE : UFMT_DOUBLE;
} if (std::holds_alternative<int64_t>(contents)) { return UFMT_INT64;
} if (std::holds_alternative<UnicodeString>(contents)) { return UFMT_STRING;
} if (isDecimal()) { switch (std::get_if<icu::Formattable>(&contents)->getType()) { case icu::Formattable::Type::kLong: { return UFMT_LONG;
} case icu::Formattable::Type::kDouble: { return UFMT_DOUBLE;
} default: { return UFMT_INT64;
}
}
} if (std::holds_alternative<const FormattableObject*>(contents)) { return UFMT_OBJECT;
} return UFMT_ARRAY;
}
switch (getType()) { case UFMT_LONG: case UFMT_INT64: { return *std::get_if<int64_t>(&contents);
} case UFMT_DOUBLE: { return icu::Formattable(*std::get_if<double>(&contents)).getInt64(status);
} default: {
status = U_INVALID_FORMAT_ERROR; return 0;
}
}
}
icu::Formattable Formattable::asICUFormattable(UErrorCode& status) const { if (U_FAILURE(status)) { return {};
} // Type must not be UFMT_ARRAY or UFMT_OBJECT if (getType() == UFMT_ARRAY || getType() == UFMT_OBJECT) {
status = U_ILLEGAL_ARGUMENT_ERROR; return {};
}
if (isDecimal()) { return *std::get_if<icu::Formattable>(&contents);
}
switch (getType()) { case UFMT_DATE: { return icu::Formattable(*std::get_if<double>(&contents), icu::Formattable::kIsDate);
} case UFMT_DOUBLE: { return icu::Formattable(*std::get_if<double>(&contents));
} case UFMT_LONG: { return icu::Formattable(static_cast<int32_t>(*std::get_if<double>(&contents)));
} case UFMT_INT64: { return icu::Formattable(*std::get_if<int64_t>(&contents));
} case UFMT_STRING: { return icu::Formattable(*std::get_if<UnicodeString>(&contents));
} default: { // Already checked for UFMT_ARRAY and UFMT_OBJECT return icu::Formattable();
}
}
}
// Called when output is required and the contents are an unevaluated `Formattable`; // formats the source `Formattable` to a string with defaults, if it can be // formatted with a default formatter static FormattedPlaceholder formatWithDefaults(const Locale& locale, const FormattedPlaceholder& input, UErrorCode& status) { if (U_FAILURE(status)) { return {};
}
const Formattable& toFormat = input.asFormattable(); // Try as decimal number first if (toFormat.isNumeric()) { // Note: the ICU Formattable has to be created here since the StringPiece // refers to state inside the Formattable; so otherwise we'll have a reference // to a temporary object
icu::Formattable icuFormattable = toFormat.asICUFormattable(status);
StringPiece asDecimal = icuFormattable.getDecimalNumber(status); if (U_FAILURE(status)) { return {};
} if (asDecimal != nullptr) { return FormattedPlaceholder(input, FormattedValue(formatNumberWithDefaults(locale, asDecimal, status)));
}
}
UFormattableType type = toFormat.getType(); switch (type) { case UFMT_DATE: {
UnicodeString result;
UDate d = toFormat.getDate(status);
U_ASSERT(U_SUCCESS(status));
formatDateWithDefaults(locale, d, result, status); return FormattedPlaceholder(input, FormattedValue(std::move(result)));
} case UFMT_DOUBLE: { double d = toFormat.getDouble(status);
U_ASSERT(U_SUCCESS(status)); return FormattedPlaceholder(input, FormattedValue(formatNumberWithDefaults(locale, d, status)));
} case UFMT_LONG: {
int32_t l = toFormat.getLong(status);
U_ASSERT(U_SUCCESS(status)); return FormattedPlaceholder(input, FormattedValue(formatNumberWithDefaults(locale, l, status)));
} case UFMT_INT64: {
int64_t i = toFormat.getInt64Value(status);
U_ASSERT(U_SUCCESS(status)); return FormattedPlaceholder(input, FormattedValue(formatNumberWithDefaults(locale, i, status)));
} case UFMT_STRING: { const UnicodeString& s = toFormat.getString(status);
U_ASSERT(U_SUCCESS(status)); return FormattedPlaceholder(input, FormattedValue(UnicodeString(s)));
} default: { // No default formatters for other types; use fallback
status = U_MF_FORMATTING_ERROR; // Note: it would be better to set an internal formatting error so that a string // (e.g. the type tag) can be provided. However, this method is called by the // public method formatToString() and thus can't take a MessageContext return FormattedPlaceholder(input.getFallback());
}
}
}
// Called when string output is required; forces output to be produced // if none is present (including formatting number output as a string)
UnicodeString FormattedPlaceholder::formatToString(const Locale& locale,
UErrorCode& status) const { if (U_FAILURE(status)) { return {};
} if (isFallback() || isNullOperand()) { return fallbackToString(fallback);
}
// Evaluated value: either just return the string, or format the number // as a string and return it if (isEvaluated()) { if (formatted.isString()) { return formatted.getString();
} else { return formatted.getNumber().toString(status);
}
} // Unevaluated value: first evaluate it fully, then format
UErrorCode savedStatus = status;
FormattedPlaceholder evaluated = formatWithDefaults(locale, *this, status); if (status == U_MF_FORMATTING_ERROR) {
U_ASSERT(evaluated.isFallback()); return evaluated.getFallback();
} // Ignore U_USING_DEFAULT_WARNING if (status == U_USING_DEFAULT_WARNING) {
status = savedStatus;
} return evaluated.formatToString(locale, status);
}
} // namespace message2
U_NAMESPACE_END
#endif/* #if !UCONFIG_NO_MF2 */
#endif/* #if !UCONFIG_NO_FORMATTING */
Messung V0.5
¤ Dauer der Verarbeitung: 0.0 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.