U_CAPI USimpleNumber* U_EXPORT2
usnum_openForInt64(int64_t value, UErrorCode* ec) {
- auto* impl = new USimpleNumberData();
- if (impl == nullptr) {
+ auto* number = new USimpleNumberData();
+ if (number == nullptr) {
*ec = U_MEMORY_ALLOCATION_ERROR;
return nullptr;
}
- impl->fNumber = SimpleNumber::forInt64(value, *ec);
- return impl->exportForC();
+ number->fNumber = SimpleNumber::forInt64(value, *ec);
+ return number->exportForC();
+}
+
+U_CAPI void U_EXPORT2
+usnum_setToInt64(USimpleNumber* unumber, int64_t value, UErrorCode* ec) {
+ auto* number = USimpleNumberData::validate(unumber, *ec);
+ if (U_FAILURE(*ec)) {
+ return;
+ }
+ number->fNumber = SimpleNumber::forInt64(value, *ec);
}
U_CAPI void U_EXPORT2
}
U_CAPI void U_EXPORT2
-usnumf_formatAndAdoptNumber(
+usnumf_format(
const USimpleNumberFormatter* uformatter,
USimpleNumber* unumber,
UFormattedNumber* uresult,
auto* number = USimpleNumberData::validate(unumber, *ec);
auto* result = UFormattedNumberApiHelper::validate(uresult, *ec);
if (U_FAILURE(*ec)) {
- delete number;
return;
}
auto localResult = formatter->fFormatter.format(std::move(number->fNumber), *ec);
- result->setTo(std::move(localResult));
- delete number;
+ if (U_FAILURE(*ec)) {
+ return;
+ }
+ result->setTo(std::move(localResult));
}
U_CAPI void U_EXPORT2
* These functions render locale-aware number strings but without the bells and whistles found in
* other number formatting APIs such as those in unumberformatter.h, like units and currencies.
*
+ * Example using C++ helpers:
+ *
* <pre>
* LocalUSimpleNumberFormatterPointer uformatter(usnumf_openForLocale("de-CH", status));
* LocalUFormattedNumberPointer uresult(unumf_openResult(status));
* u"55",
* ufmtval_getString(unumf_resultAsValue(uresult.getAlias(), status), nullptr, status));
* </pre>
+ *
+ * Example using pure C:
+ *
+ * <pre>
+ * UErrorCode ec = U_ZERO_ERROR;
+ * USimpleNumberFormatter* uformatter = usnumf_openForLocale("bn", &ec);
+ * USimpleNumber* unumber = usnum_openForInt64(1000007, &ec);
+ * UFormattedNumber* uresult = unumf_openResult(&ec);
+ * usnumf_format(uformatter, unumber, uresult, &ec);
+ * int32_t len;
+ * const UChar* str = ufmtval_getString(unumf_resultAsValue(uresult, &ec), &len, &ec);
+ * if (assertSuccess("Formatting end-to-end", &ec)) {
+ * assertUEquals("Should produce a result in Bangla digits", u"১০,০০,০০৭", str);
+ * }
+
+ * // Cleanup:
+ * unumf_closeResult(uresult);
+ * usnum_close(unumber);
+ * usnumf_close(uformatter);
+ * </pre>
*/
#ifndef U_HIDE_DRAFT_API
usnum_openForInt64(int64_t value, UErrorCode* ec);
+/**
+ * Overwrites the value in a USimpleNumber to an int64_t.
+ *
+ * This can be used to reset the number value after formatting.
+ *
+ * @draft ICU 73
+ */
+U_CAPI void U_EXPORT2
+usnum_setToInt64(USimpleNumber* unumber, int64_t value, UErrorCode* ec);
+
+
/**
* Changes the value of the USimpleNumber by a power of 10.
*
/**
* Formats a number using this SimpleNumberFormatter.
*
- * The USimpleNumber is adopted and must not be freed after calling this function,
- * even if the function sets an error code. If you use LocalUSimpleNumberPointer,
- * call `.orphan()` when passing it to this function.
+ * The USimpleNumber is cleared after calling this function. It can be re-used via
+ * usnum_setToInt64.
*
* @draft ICU 73
*/
U_CAPI void U_EXPORT2
-usnumf_formatAndAdoptNumber(
+usnumf_format(
const USimpleNumberFormatter* uformatter,
USimpleNumber* unumber,
UFormattedNumber* uresult,
#include <stdbool.h>
#include <stdio.h>
#include "unicode/unumberformatter.h"
+#include "unicode/usimplenumberformatter.h"
#include "unicode/umisc.h"
#include "unicode/unum.h"
#include "unicode/ustring.h"
static void TestExampleCode(void);
+static void TestSimpleNumberFormatterExample(void);
+
+static void TestSimpleNumberFormatterFull(void);
+
static void TestFormattedValue(void);
static void TestSkeletonParseError(void);
TESTCASE(TestSkeletonFormatToString);
TESTCASE(TestSkeletonFormatToFields);
TESTCASE(TestExampleCode);
+ TESTCASE(TestSimpleNumberFormatterExample);
+ TESTCASE(TestSimpleNumberFormatterFull);
TESTCASE(TestFormattedValue);
TESTCASE(TestSkeletonParseError);
TESTCASE(TestToDecimalNumber);
}
+static void TestSimpleNumberFormatterExample() {
+ // This is the example in usimplenumberformatter.h
+ UErrorCode ec = U_ZERO_ERROR;
+ USimpleNumberFormatter* uformatter = usnumf_openForLocale("bn", &ec);
+ USimpleNumber* unumber = usnum_openForInt64(1000007, &ec);
+ UFormattedNumber* uresult = unumf_openResult(&ec);
+ usnumf_format(uformatter, unumber, uresult, &ec);
+ int32_t len;
+ const UChar* str = ufmtval_getString(unumf_resultAsValue(uresult, &ec), &len, &ec);
+ if (assertSuccess("Formatting end-to-end 1", &ec)) {
+ assertUEquals("Should produce a result in Bangla digits", u"১০,০০,০০৭", str);
+ }
+
+ // Cleanup:
+ unumf_closeResult(uresult);
+ usnum_close(unumber);
+ usnumf_close(uformatter);
+}
+
+
+static void TestSimpleNumberFormatterFull() {
+ UErrorCode ec = U_ZERO_ERROR;
+ USimpleNumberFormatter* uformatter = usnumf_openForLocaleAndGroupingStrategy("de-CH", UNUM_GROUPING_ON_ALIGNED, &ec);
+ UFormattedNumber* uresult = unumf_openResult(&ec);
+
+ usnumf_formatInt64(uformatter, 4321, uresult, &ec);
+ int32_t len;
+ const UChar* str = str = ufmtval_getString(unumf_resultAsValue(uresult, &ec), &len, &ec);
+ if (assertSuccess("Formatting end-to-end 2", &ec)) {
+ assertUEquals("Should produce a result with Swiss symbols", u"4’321", str);
+ }
+
+ USimpleNumber* unumber = usnum_openForInt64(1000007, &ec);
+ usnum_setToInt64(unumber, 98765, &ec);
+ usnum_multiplyByPowerOfTen(unumber, -2, &ec);
+ usnum_roundTo(unumber, -1, UNUM_ROUND_HALFDOWN, &ec);
+ usnum_setMinimumIntegerDigits(unumber, 4, &ec);
+ usnum_setMinimumFractionDigits(unumber, 3, &ec);
+ usnum_truncateStart(unumber, 1, &ec);
+ usnum_setSign(unumber, UNUM_SIMPLE_NUMBER_PLUS_SIGN, &ec);
+
+ usnumf_format(uformatter, unumber, uresult, &ec);
+ str = ufmtval_getString(unumf_resultAsValue(uresult, &ec), &len, &ec);
+ if (assertSuccess("Formatting end-to-end 3", &ec)) {
+ assertUEquals("Should produce a result with mutated number", u"+0’007.600", str);
+ }
+
+ // Cleanup:
+ unumf_closeResult(uresult);
+ usnum_close(unumber);
+ usnumf_close(uformatter);
+}
+
+
static void TestFormattedValue() {
UErrorCode ec = U_ZERO_ERROR;
UNumberFormatter* uformatter = unumf_openForSkeletonAndLocale(
ufmtval_getString(unumf_resultAsValue(uresult.getAlias(), status), nullptr, status));
LocalUSimpleNumberPointer unumber(usnum_openForInt64(44, status));
- usnumf_formatAndAdoptNumber(uformatter.getAlias(), unumber.orphan(), uresult.getAlias(), status);
+ usnumf_format(uformatter.getAlias(), unumber.getAlias(), uresult.getAlias(), status);
assertEquals("",
u"44",
ufmtval_getString(unumf_resultAsValue(uresult.getAlias(), status), nullptr, status));
- unumber.adoptInstead(usnum_openForInt64(2335, status));
+ // Can't re-use a number without setting it again
+ usnumf_format(uformatter.getAlias(), unumber.getAlias(), uresult.getAlias(), status);
+ status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR);
+ usnum_multiplyByPowerOfTen(unumber.getAlias(), 0, status);
+ status.expectErrorAndReset(U_INVALID_STATE_ERROR);
+
+ usnum_setToInt64(unumber.getAlias(), 2335, status);
usnum_multiplyByPowerOfTen(unumber.getAlias(), -2, status);
usnum_roundTo(unumber.getAlias(), -1, UNUM_ROUND_HALFEVEN, status);
usnum_truncateStart(unumber.getAlias(), 1, status);
usnum_setMinimumFractionDigits(unumber.getAlias(), 3, status);
usnum_setMinimumIntegerDigits(unumber.getAlias(), 3, status);
- usnumf_formatAndAdoptNumber(uformatter.getAlias(), unumber.orphan(), uresult.getAlias(), status);
+ usnumf_format(uformatter.getAlias(), unumber.getAlias(), uresult.getAlias(), status);
assertEquals("",
u"003.400",
ufmtval_getString(unumf_resultAsValue(uresult.getAlias(), status), nullptr, status));
+
+ // Setting twice should overwrite the first value
+ usnum_setToInt64(unumber.getAlias(), 1111, status);
+ usnum_setToInt64(unumber.getAlias(), 2222, status);
+ usnumf_format(uformatter.getAlias(), unumber.getAlias(), uresult.getAlias(), status);
+ assertEquals("",
+ u"2’222",
+ ufmtval_getString(unumf_resultAsValue(uresult.getAlias(), status), nullptr, status));
+
+ {
+ // This is the exact example in usimplenumberformatter.h
+ LocalUSimpleNumberFormatterPointer uformatter(usnumf_openForLocale("de-CH", status));
+ LocalUFormattedNumberPointer uresult(unumf_openResult(status));
+ usnumf_formatInt64(uformatter.getAlias(), 55, uresult.getAlias(), status);
+ assertEquals("",
+ u"55",
+ ufmtval_getString(unumf_resultAsValue(uresult.getAlias(), status), nullptr, status));
+ }
}