number_integerwidth.cpp 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // © 2017 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. #include "unicode/utypes.h"
  4. #if !UCONFIG_NO_FORMATTING
  5. #include "unicode/numberformatter.h"
  6. #include "number_types.h"
  7. #include "number_decimalquantity.h"
  8. using namespace icu;
  9. using namespace icu::number;
  10. using namespace icu::number::impl;
  11. IntegerWidth::IntegerWidth(digits_t minInt, digits_t maxInt, bool formatFailIfMoreThanMaxDigits) {
  12. fUnion.minMaxInt.fMinInt = minInt;
  13. fUnion.minMaxInt.fMaxInt = maxInt;
  14. fUnion.minMaxInt.fFormatFailIfMoreThanMaxDigits = formatFailIfMoreThanMaxDigits;
  15. }
  16. IntegerWidth IntegerWidth::zeroFillTo(int32_t minInt) {
  17. if (minInt >= 0 && minInt <= kMaxIntFracSig) {
  18. return {static_cast<digits_t>(minInt), -1, false};
  19. } else {
  20. return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
  21. }
  22. }
  23. IntegerWidth IntegerWidth::truncateAt(int32_t maxInt) {
  24. if (fHasError) { return *this; } // No-op on error
  25. digits_t minInt = fUnion.minMaxInt.fMinInt;
  26. if (maxInt >= 0 && maxInt <= kMaxIntFracSig && minInt <= maxInt) {
  27. return {minInt, static_cast<digits_t>(maxInt), false};
  28. } else if (maxInt == -1) {
  29. return {minInt, -1, false};
  30. } else {
  31. return {U_NUMBER_ARG_OUTOFBOUNDS_ERROR};
  32. }
  33. }
  34. void IntegerWidth::apply(impl::DecimalQuantity& quantity, UErrorCode& status) const {
  35. if (U_FAILURE(status)) {
  36. return;
  37. }
  38. if (fHasError) {
  39. status = U_ILLEGAL_ARGUMENT_ERROR;
  40. } else if (fUnion.minMaxInt.fMaxInt == -1) {
  41. quantity.setMinInteger(fUnion.minMaxInt.fMinInt);
  42. } else {
  43. // Enforce the backwards-compatibility feature "FormatFailIfMoreThanMaxDigits"
  44. if (fUnion.minMaxInt.fFormatFailIfMoreThanMaxDigits &&
  45. fUnion.minMaxInt.fMaxInt < quantity.getMagnitude()) {
  46. status = U_ILLEGAL_ARGUMENT_ERROR;
  47. }
  48. quantity.setMinInteger(fUnion.minMaxInt.fMinInt);
  49. quantity.applyMaxInteger(fUnion.minMaxInt.fMaxInt);
  50. }
  51. }
  52. bool IntegerWidth::operator==(const IntegerWidth& other) const {
  53. // Private operator==; do error and bogus checking first!
  54. U_ASSERT(!fHasError);
  55. U_ASSERT(!other.fHasError);
  56. U_ASSERT(!isBogus());
  57. U_ASSERT(!other.isBogus());
  58. return fUnion.minMaxInt.fMinInt == other.fUnion.minMaxInt.fMinInt &&
  59. fUnion.minMaxInt.fMaxInt == other.fUnion.minMaxInt.fMaxInt;
  60. }
  61. #endif /* #if !UCONFIG_NO_FORMATTING */