summaryrefslogtreecommitdiffstats
path: root/mozglue/misc/decimal/moz-constexpr-decimal.patch
blob: 845352bd05306d1099984ca6fc24e53ce58095fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
index 7fdf38c5cb7c3..8bce5c3312f55 100644
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -187,16 +187,18 @@ static const nsAttrValue::EnumTable kCaptureTable[] = {
 
 static const nsAttrValue::EnumTable* kCaptureDefault = &kCaptureTable[2];
 
-const Decimal HTMLInputElement::kStepScaleFactorDate = Decimal(86400000);
-const Decimal HTMLInputElement::kStepScaleFactorNumberRange = Decimal(1);
-const Decimal HTMLInputElement::kStepScaleFactorTime = Decimal(1000);
-const Decimal HTMLInputElement::kStepScaleFactorMonth = Decimal(1);
-const Decimal HTMLInputElement::kStepScaleFactorWeek = Decimal(7 * 86400000);
-const Decimal HTMLInputElement::kDefaultStepBase = Decimal(0);
-const Decimal HTMLInputElement::kDefaultStepBaseWeek = Decimal(-259200000);
-const Decimal HTMLInputElement::kDefaultStep = Decimal(1);
-const Decimal HTMLInputElement::kDefaultStepTime = Decimal(60);
-const Decimal HTMLInputElement::kStepAny = Decimal(0);
+using namespace blink;
+
+constexpr Decimal HTMLInputElement::kStepScaleFactorDate(86400000_d);
+constexpr Decimal HTMLInputElement::kStepScaleFactorNumberRange(1_d);
+constexpr Decimal HTMLInputElement::kStepScaleFactorTime(1000_d);
+constexpr Decimal HTMLInputElement::kStepScaleFactorMonth(1_d);
+constexpr Decimal HTMLInputElement::kStepScaleFactorWeek(7 * 86400000_d);
+constexpr Decimal HTMLInputElement::kDefaultStepBase(0_d);
+constexpr Decimal HTMLInputElement::kDefaultStepBaseWeek(-259200000_d);
+constexpr Decimal HTMLInputElement::kDefaultStep(1_d);
+constexpr Decimal HTMLInputElement::kDefaultStepTime(60_d);
+constexpr Decimal HTMLInputElement::kStepAny(0_d);
 
 const double HTMLInputElement::kMinimumYear = 1;
 const double HTMLInputElement::kMaximumYear = 275760;
diff --git a/mozglue/misc/decimal/Decimal.cpp b/mozglue/misc/decimal/Decimal.cpp
index cc828e28439f5..7d2bcfa712c5d 100644
--- a/mozglue/misc/decimal/Decimal.cpp
+++ b/mozglue/misc/decimal/Decimal.cpp
@@ -41,12 +41,6 @@ namespace blink {
 
 namespace DecimalPrivate {
 
-static int const ExponentMax = 1023;
-static int const ExponentMin = -1023;
-static int const Precision = 18;
-
-static const uint64_t MaxCoefficient = UINT64_C(0xDE0B6B3A763FFFF); // 999999999999999999 == 18 9's
-
 // This class handles Decimal special values.
 class SpecialValueHandler {
     STACK_ALLOCATED();
@@ -230,43 +224,6 @@ static uint64_t scaleUp(uint64_t x, int n)
 
 using namespace DecimalPrivate;
 
-Decimal::EncodedData::EncodedData(Sign sign, FormatClass formatClass)
-    : m_coefficient(0)
-    , m_exponent(0)
-    , m_formatClass(formatClass)
-    , m_sign(sign)
-{
-}
-
-Decimal::EncodedData::EncodedData(Sign sign, int exponent, uint64_t coefficient)
-    : m_formatClass(coefficient ? ClassNormal : ClassZero)
-    , m_sign(sign)
-{
-    if (exponent >= ExponentMin && exponent <= ExponentMax) {
-        while (coefficient > MaxCoefficient) {
-            coefficient /= 10;
-            ++exponent;
-        }
-    }
-
-    if (exponent > ExponentMax) {
-        m_coefficient = 0;
-        m_exponent = 0;
-        m_formatClass = ClassInfinity;
-        return;
-    }
-
-    if (exponent < ExponentMin) {
-        m_coefficient = 0;
-        m_exponent = 0;
-        m_formatClass = ClassZero;
-        return;
-    }
-
-    m_coefficient = coefficient;
-    m_exponent = static_cast<int16_t>(exponent);
-}
-
 bool Decimal::EncodedData::operator==(const EncodedData& another) const
 {
     return m_sign == another.m_sign
@@ -275,15 +232,12 @@ bool Decimal::EncodedData::operator==(const EncodedData& another) const
         && m_coefficient == another.m_coefficient;
 }
 
+
 Decimal::Decimal(int32_t i32)
-    : m_data(i32 < 0 ? Negative : Positive, 0, i32 < 0 ? static_cast<uint64_t>(-static_cast<int64_t>(i32)) : static_cast<uint64_t>(i32))
-{
-}
+    : Decimal(DecimalLiteral{i32}) {}
 
 Decimal::Decimal(Sign sign, int exponent, uint64_t coefficient)
-    : m_data(sign, coefficient ? exponent : 0, coefficient)
-{
-}
+    : m_data(sign, coefficient ? exponent : 0, coefficient) {}
 
 Decimal::Decimal(const EncodedData& data)
     : m_data(data)
diff --git a/mozglue/misc/decimal/Decimal.h b/mozglue/misc/decimal/Decimal.h
index 10d0e2c7cefa3..4bb9a841e585f 100644
--- a/mozglue/misc/decimal/Decimal.h
+++ b/mozglue/misc/decimal/Decimal.h
@@ -65,9 +65,28 @@
 namespace blink {
 
 namespace DecimalPrivate {
+constexpr int ExponentMax = 1023;
+constexpr int ExponentMin = -1023;
+constexpr int Precision = 18;
+
+static const uint64_t MaxCoefficient = UINT64_C(0xDE0B6B3A763FFFF);  // 999999999999999999 == 18 9's
 class SpecialValueHandler;
 }
 
+struct DecimalLiteral {
+  int32_t value;
+  friend constexpr DecimalLiteral operator*(int32_t lhs, DecimalLiteral rhs) {
+    return {lhs * rhs.value};
+  }
+  constexpr DecimalLiteral operator-() {
+    return {-value};
+  }
+};
+
+constexpr DecimalLiteral operator""_d(unsigned long long value) {
+  return {static_cast<int32_t>(value)};
+}
+
 // This class represents decimal base floating point number.
 //
 // FIXME: Once all C++ compiler support decimal type, we should replace this
@@ -88,7 +107,32 @@ public:
         friend class Decimal;
         friend class DecimalPrivate::SpecialValueHandler;
     public:
-        EncodedData(Sign, int exponent, uint64_t coefficient);
+     constexpr EncodedData(Sign sign, int exponent, uint64_t coefficient)
+         : m_coefficient(0),
+           m_exponent(0),
+           m_formatClass(coefficient ? ClassNormal : ClassZero),
+           m_sign(sign) {
+       if (exponent >= DecimalPrivate::ExponentMin &&
+           exponent <= DecimalPrivate::ExponentMax) {
+         while (coefficient > DecimalPrivate::MaxCoefficient) {
+           coefficient /= 10;
+           ++exponent;
+         }
+       }
+
+       if (exponent > DecimalPrivate::ExponentMax) {
+         m_formatClass = ClassInfinity;
+         return;
+       }
+
+       if (exponent < DecimalPrivate::ExponentMin) {
+         m_formatClass = ClassZero;
+         return;
+       }
+
+       m_coefficient = coefficient;
+       m_exponent = static_cast<int16_t>(exponent);
+     }
 
         bool operator==(const EncodedData&) const;
         bool operator!=(const EncodedData& another) const { return !operator==(another); }
@@ -112,7 +156,12 @@ public:
             ClassZero,
         };
 
-        EncodedData(Sign, FormatClass);
+        constexpr EncodedData(Sign sign, FormatClass formatClass)
+            : m_coefficient(0),
+              m_exponent(0),
+              m_formatClass(formatClass),
+              m_sign(sign) {}
+
         FormatClass formatClass() const { return m_formatClass; }
 
         uint64_t m_coefficient;
@@ -121,8 +170,13 @@ public:
         Sign m_sign;
     };
 
-    MFBT_API explicit Decimal(int32_t = 0);
-    MFBT_API Decimal(Sign, int exponent, uint64_t coefficient);
+    constexpr explicit Decimal(DecimalLiteral i32)
+    : m_data(i32.value < 0 ? Negative : Positive, 0,
+             i32.value < 0 ? static_cast<uint64_t>(-static_cast<int64_t>(i32.value))
+                     : static_cast<uint64_t>(i32.value)) {}
+
+    MFBT_API explicit Decimal(int32_t i32 = 0);
+    MFBT_API Decimal(Sign sign, int exponent, uint64_t coefficient);
     MFBT_API Decimal(const Decimal&);
 
     MFBT_API Decimal& operator=(const Decimal&);
@@ -209,6 +263,7 @@ private:
 
 namespace mozilla {
 typedef blink::Decimal Decimal;
+using blink::operator""_d;
 } // namespace mozilla
 
 #undef USING_FAST_MALLOC