Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/intl/icu/source/i18n/number_multiplier.cpp
Line
Count
Source (jump to first uncovered line)
1
// © 2018 and later: Unicode, Inc. and others.
2
// License & terms of use: http://www.unicode.org/copyright.html
3
4
#include "unicode/utypes.h"
5
6
#if !UCONFIG_NO_FORMATTING
7
8
// Allow implicit conversion from char16_t* to UnicodeString for this file:
9
// Helpful in toString methods and elsewhere.
10
#define UNISTR_FROM_STRING_EXPLICIT
11
12
#include "number_decnum.h"
13
#include "number_types.h"
14
#include "number_multiplier.h"
15
#include "numparse_validators.h"
16
#include "number_utils.h"
17
#include "decNumber.h"
18
19
using namespace icu;
20
using namespace icu::number;
21
using namespace icu::number::impl;
22
using namespace icu::numparse::impl;
23
24
25
Scale::Scale(int32_t magnitude, DecNum* arbitraryToAdopt)
26
0
        : fMagnitude(magnitude), fArbitrary(arbitraryToAdopt), fError(U_ZERO_ERROR) {
27
0
    if (fArbitrary != nullptr) {
28
0
        // Attempt to convert the DecNum to a magnitude multiplier.
29
0
        fArbitrary->normalize();
30
0
        if (fArbitrary->getRawDecNumber()->digits == 1 && fArbitrary->getRawDecNumber()->lsu[0] == 1 &&
31
0
            !fArbitrary->isNegative()) {
32
0
            // Success!
33
0
            fMagnitude += fArbitrary->getRawDecNumber()->exponent;
34
0
            delete fArbitrary;
35
0
            fArbitrary = nullptr;
36
0
        }
37
0
    }
38
0
}
39
40
Scale::Scale(const Scale& other)
41
0
        : fMagnitude(other.fMagnitude), fArbitrary(nullptr), fError(other.fError) {
42
0
    if (other.fArbitrary != nullptr) {
43
0
        UErrorCode localStatus = U_ZERO_ERROR;
44
0
        fArbitrary = new DecNum(*other.fArbitrary, localStatus);
45
0
    }
46
0
}
47
48
0
Scale& Scale::operator=(const Scale& other) {
49
0
    fMagnitude = other.fMagnitude;
50
0
    if (other.fArbitrary != nullptr) {
51
0
        UErrorCode localStatus = U_ZERO_ERROR;
52
0
        fArbitrary = new DecNum(*other.fArbitrary, localStatus);
53
0
    } else {
54
0
        fArbitrary = nullptr;
55
0
    }
56
0
    fError = other.fError;
57
0
    return *this;
58
0
}
59
60
Scale::Scale(Scale&& src) U_NOEXCEPT
61
0
        : fMagnitude(src.fMagnitude), fArbitrary(src.fArbitrary), fError(src.fError) {
62
0
    // Take ownership away from src if necessary
63
0
    src.fArbitrary = nullptr;
64
0
}
65
66
0
Scale& Scale::operator=(Scale&& src) U_NOEXCEPT {
67
0
    fMagnitude = src.fMagnitude;
68
0
    fArbitrary = src.fArbitrary;
69
0
    fError = src.fError;
70
0
    // Take ownership away from src if necessary
71
0
    src.fArbitrary = nullptr;
72
0
    return *this;
73
0
}
74
75
0
Scale::~Scale() {
76
0
    delete fArbitrary;
77
0
}
78
79
80
0
Scale Scale::none() {
81
0
    return {0, nullptr};
82
0
}
83
84
0
Scale Scale::powerOfTen(int32_t power) {
85
0
    return {power, nullptr};
86
0
}
87
88
0
Scale Scale::byDecimal(StringPiece multiplicand) {
89
0
    UErrorCode localError = U_ZERO_ERROR;
90
0
    LocalPointer<DecNum> decnum(new DecNum(), localError);
91
0
    if (U_FAILURE(localError)) {
92
0
        return {localError};
93
0
    }
94
0
    decnum->setTo(multiplicand, localError);
95
0
    if (U_FAILURE(localError)) {
96
0
        return {localError};
97
0
    }
98
0
    return {0, decnum.orphan()};
99
0
}
100
101
0
Scale Scale::byDouble(double multiplicand) {
102
0
    UErrorCode localError = U_ZERO_ERROR;
103
0
    LocalPointer<DecNum> decnum(new DecNum(), localError);
104
0
    if (U_FAILURE(localError)) {
105
0
        return {localError};
106
0
    }
107
0
    decnum->setTo(multiplicand, localError);
108
0
    if (U_FAILURE(localError)) {
109
0
        return {localError};
110
0
    }
111
0
    return {0, decnum.orphan()};
112
0
}
113
114
0
Scale Scale::byDoubleAndPowerOfTen(double multiplicand, int32_t power) {
115
0
    UErrorCode localError = U_ZERO_ERROR;
116
0
    LocalPointer<DecNum> decnum(new DecNum(), localError);
117
0
    if (U_FAILURE(localError)) {
118
0
        return {localError};
119
0
    }
120
0
    decnum->setTo(multiplicand, localError);
121
0
    if (U_FAILURE(localError)) {
122
0
        return {localError};
123
0
    }
124
0
    return {power, decnum.orphan()};
125
0
}
126
127
0
void Scale::applyTo(impl::DecimalQuantity& quantity) const {
128
0
    quantity.adjustMagnitude(fMagnitude);
129
0
    if (fArbitrary != nullptr) {
130
0
        UErrorCode localStatus = U_ZERO_ERROR;
131
0
        quantity.multiplyBy(*fArbitrary, localStatus);
132
0
    }
133
0
}
134
135
0
void Scale::applyReciprocalTo(impl::DecimalQuantity& quantity) const {
136
0
    quantity.adjustMagnitude(-fMagnitude);
137
0
    if (fArbitrary != nullptr) {
138
0
        UErrorCode localStatus = U_ZERO_ERROR;
139
0
        quantity.divideBy(*fArbitrary, localStatus);
140
0
    }
141
0
}
142
143
144
void
145
0
MultiplierFormatHandler::setAndChain(const Scale& multiplier, const MicroPropsGenerator* parent) {
146
0
    this->multiplier = multiplier;
147
0
    this->parent = parent;
148
0
}
149
150
void MultiplierFormatHandler::processQuantity(DecimalQuantity& quantity, MicroProps& micros,
151
0
                                              UErrorCode& status) const {
152
0
    parent->processQuantity(quantity, micros, status);
153
0
    multiplier.applyTo(quantity);
154
0
}
155
156
#endif /* #if !UCONFIG_NO_FORMATTING */