1 | /* |
2 | * Copyright (C) 2012 Intel Corporation |
3 | * Copyright (C) 2019 Apple Inc. All rights reserved. |
4 | * |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions |
7 | * are met: |
8 | * 1. Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions and the following disclaimer. |
10 | * 2. Redistributions in binary form must reproduce the above copyright |
11 | * notice, this list of conditions and the following disclaimer in the |
12 | * documentation and/or other materials provided with the distribution. |
13 | * |
14 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
16 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
17 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
18 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
24 | * THE POSSIBILITY OF SUCH DAMAGE. |
25 | */ |
26 | |
27 | #include "config.h" |
28 | |
29 | #include <wtf/MathExtras.h> |
30 | |
31 | namespace TestWebKitAPI { |
32 | |
33 | TEST(WTF, Lrint) |
34 | { |
35 | EXPECT_EQ(lrint(-7.5), -8); |
36 | EXPECT_EQ(lrint(-8.5), -8); |
37 | EXPECT_EQ(lrint(-0.5), 0); |
38 | EXPECT_EQ(lrint(0.5), 0); |
39 | EXPECT_EQ(lrint(-0.5), 0); |
40 | EXPECT_EQ(lrint(1.3), 1); |
41 | EXPECT_EQ(lrint(1.7), 2); |
42 | EXPECT_EQ(lrint(0), 0); |
43 | EXPECT_EQ(lrint(-0), 0); |
44 | if (sizeof(long int) == 8) { |
45 | // Largest double number with 0.5 precision and one halfway rounding case below. |
46 | EXPECT_EQ(lrint(pow(2.0, 52) - 0.5), pow(2.0, 52)); |
47 | EXPECT_EQ(lrint(pow(2.0, 52) - 1.5), pow(2.0, 52) - 2); |
48 | // Smallest double number with 0.5 precision and one halfway rounding case above. |
49 | EXPECT_EQ(lrint(-pow(2.0, 52) + 0.5), -pow(2.0, 52)); |
50 | EXPECT_EQ(lrint(-pow(2.0, 52) + 1.5), -pow(2.0, 52) + 2); |
51 | } |
52 | } |
53 | |
54 | TEST(WTF, clampToIntLong) |
55 | { |
56 | if (sizeof(long) == sizeof(int)) |
57 | return; |
58 | |
59 | long maxInt = std::numeric_limits<int>::max(); |
60 | long minInt = std::numeric_limits<int>::min(); |
61 | long overflowInt = maxInt + 1; |
62 | long underflowInt = minInt - 1; |
63 | |
64 | EXPECT_GT(overflowInt, maxInt); |
65 | EXPECT_LT(underflowInt, minInt); |
66 | |
67 | EXPECT_EQ(clampTo<int>(maxInt), maxInt); |
68 | EXPECT_EQ(clampTo<int>(minInt), minInt); |
69 | |
70 | EXPECT_EQ(clampTo<int>(overflowInt), maxInt); |
71 | EXPECT_EQ(clampTo<int>(underflowInt), minInt); |
72 | } |
73 | |
74 | TEST(WTF, clampToIntLongLong) |
75 | { |
76 | long long maxInt = std::numeric_limits<int>::max(); |
77 | long long minInt = std::numeric_limits<int>::min(); |
78 | long long overflowInt = maxInt + 1; |
79 | long long underflowInt = minInt - 1; |
80 | |
81 | EXPECT_GT(overflowInt, maxInt); |
82 | EXPECT_LT(underflowInt, minInt); |
83 | |
84 | EXPECT_EQ(clampTo<int>(maxInt), maxInt); |
85 | EXPECT_EQ(clampTo<int>(minInt), minInt); |
86 | |
87 | EXPECT_EQ(clampTo<int>(overflowInt), maxInt); |
88 | EXPECT_EQ(clampTo<int>(underflowInt), minInt); |
89 | } |
90 | |
91 | TEST(WTF, clampToIntegerFloat) |
92 | { |
93 | // This test is inaccurate as floats will round the min / max integer |
94 | // due to the narrow mantissa. However it will properly checks within |
95 | // (close to the extreme) and outside the integer range. |
96 | float maxInt = std::numeric_limits<int>::max(); |
97 | float minInt = std::numeric_limits<int>::min(); |
98 | float overflowInt = maxInt * 1.1; |
99 | float underflowInt = minInt * 1.1; |
100 | |
101 | EXPECT_GT(overflowInt, maxInt); |
102 | EXPECT_LT(underflowInt, minInt); |
103 | |
104 | // If maxInt == 2^31 - 1 (ie on I32 architecture), the closest float used to represent it is 2^31. |
105 | EXPECT_NEAR(clampToInteger(maxInt), maxInt, 1); |
106 | EXPECT_EQ(clampToInteger(minInt), minInt); |
107 | |
108 | EXPECT_NEAR(clampToInteger(overflowInt), maxInt, 1); |
109 | EXPECT_EQ(clampToInteger(underflowInt), minInt); |
110 | } |
111 | |
112 | TEST(WTF, clampToIntegerDouble) |
113 | { |
114 | double maxInt = std::numeric_limits<int>::max(); |
115 | double minInt = std::numeric_limits<int>::min(); |
116 | double overflowInt = maxInt + 1; |
117 | double underflowInt = minInt - 1; |
118 | |
119 | EXPECT_GT(overflowInt, maxInt); |
120 | EXPECT_LT(underflowInt, minInt); |
121 | |
122 | EXPECT_EQ(clampToInteger(maxInt), maxInt); |
123 | EXPECT_EQ(clampToInteger(minInt), minInt); |
124 | |
125 | EXPECT_EQ(clampToInteger(overflowInt), maxInt); |
126 | EXPECT_EQ(clampToInteger(underflowInt), minInt); |
127 | } |
128 | |
129 | TEST(WTF, clampToFloat) |
130 | { |
131 | double maxFloat = std::numeric_limits<float>::max(); |
132 | double minFloat = -maxFloat; |
133 | double overflowFloat = maxFloat * 1.1; |
134 | double underflowFloat = minFloat * 1.1; |
135 | |
136 | EXPECT_GT(overflowFloat, maxFloat); |
137 | EXPECT_LT(underflowFloat, minFloat); |
138 | |
139 | EXPECT_EQ(clampToFloat(maxFloat), maxFloat); |
140 | EXPECT_EQ(clampToFloat(minFloat), minFloat); |
141 | |
142 | EXPECT_EQ(clampToFloat(overflowFloat), maxFloat); |
143 | EXPECT_EQ(clampToFloat(underflowFloat), minFloat); |
144 | |
145 | EXPECT_EQ(clampToFloat(std::numeric_limits<float>::infinity()), maxFloat); |
146 | EXPECT_EQ(clampToFloat(-std::numeric_limits<float>::infinity()), minFloat); |
147 | } |
148 | |
149 | TEST(WTF, clampToUnsignedLong) |
150 | { |
151 | if (sizeof(unsigned long) == sizeof(unsigned)) |
152 | return; |
153 | |
154 | unsigned long maxUnsigned = std::numeric_limits<unsigned>::max(); |
155 | unsigned long overflowUnsigned = maxUnsigned + 1; |
156 | |
157 | EXPECT_GT(overflowUnsigned, maxUnsigned); |
158 | |
159 | EXPECT_EQ(clampTo<unsigned>(maxUnsigned), maxUnsigned); |
160 | |
161 | EXPECT_EQ(clampTo<unsigned>(overflowUnsigned), maxUnsigned); |
162 | EXPECT_EQ(clampTo<unsigned>(-1), 0u); |
163 | } |
164 | |
165 | TEST(WTF, clampToUnsignedLongLong) |
166 | { |
167 | unsigned long long maxUnsigned = std::numeric_limits<unsigned>::max(); |
168 | unsigned long long overflowUnsigned = maxUnsigned + 1; |
169 | |
170 | EXPECT_GT(overflowUnsigned, maxUnsigned); |
171 | |
172 | EXPECT_EQ(clampTo<unsigned>(maxUnsigned), maxUnsigned); |
173 | |
174 | EXPECT_EQ(clampTo<unsigned>(overflowUnsigned), maxUnsigned); |
175 | EXPECT_EQ(clampTo<unsigned>(-1), 0u); |
176 | } |
177 | |
178 | #if !COMPILER(MSVC) |
179 | template<typename TargetType, typename SourceType> |
180 | static void testClampFloatingPointToFloatingPoint() |
181 | { |
182 | // No clamping. |
183 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(0)), static_cast<TargetType>(0)); |
184 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(1)), static_cast<TargetType>(1)); |
185 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(1.5)), static_cast<TargetType>(1.5)); |
186 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(-1)), static_cast<TargetType>(-1)); |
187 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(-1.5)), static_cast<TargetType>(-1.5)); |
188 | |
189 | // Explicit boundaries, clamped or not. |
190 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(-42), static_cast<SourceType>(-42.5)), static_cast<TargetType>(-42)); |
191 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(-43), static_cast<SourceType>(-42.5)), static_cast<TargetType>(static_cast<SourceType>(-42.5))); |
192 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(42), static_cast<SourceType>(41), static_cast<SourceType>(42.5)), static_cast<TargetType>(42)); |
193 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(43), static_cast<SourceType>(41), static_cast<SourceType>(42.5)), static_cast<TargetType>(static_cast<SourceType>(42.5))); |
194 | |
195 | // Integer bounds. |
196 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::max()) + 1), static_cast<TargetType>(std::numeric_limits<int32_t>::max()) + 1); |
197 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int64_t>::max())), static_cast<TargetType>(std::numeric_limits<int64_t>::max())); |
198 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::max()) + 1), static_cast<TargetType>(std::numeric_limits<int32_t>::max()) + 1); |
199 | |
200 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::min())), static_cast<TargetType>(std::numeric_limits<int32_t>::min())); |
201 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int64_t>::min())), static_cast<TargetType>(std::numeric_limits<int64_t>::min())); |
202 | |
203 | if (std::is_same<TargetType, double>::value && std::is_same<SourceType, float>::value) { |
204 | // If the source is float and target is double, the input of those cases has lost bits in float. |
205 | // In that case, we also round the expectation to float. |
206 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::max())), static_cast<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::max()))); |
207 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::min()) - 1), static_cast<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::min()) - 1)); |
208 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::min()) - 1), static_cast<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::min()) - 1)); |
209 | } else { |
210 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::max())), static_cast<TargetType>(std::numeric_limits<int32_t>::max())); |
211 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::min()) - 1), static_cast<TargetType>(std::numeric_limits<int32_t>::min()) - 1); |
212 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<int32_t>::min()) - 1), static_cast<TargetType>(std::numeric_limits<int32_t>::min()) - 1); |
213 | } |
214 | |
215 | // At the limit. |
216 | EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<TargetType>::max()), std::numeric_limits<TargetType>::max()); |
217 | EXPECT_EQ(clampTo<TargetType>(-std::numeric_limits<TargetType>::max()), -std::numeric_limits<TargetType>::max()); |
218 | |
219 | // At Epsilon from the limit. |
220 | TargetType epsilon = std::numeric_limits<TargetType>::epsilon(); |
221 | EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<TargetType>::max() - epsilon), std::numeric_limits<TargetType>::max() - epsilon); |
222 | EXPECT_EQ(clampTo<TargetType>(-std::numeric_limits<TargetType>::max() + epsilon), -std::numeric_limits<TargetType>::max() + epsilon); |
223 | |
224 | // Infinity. |
225 | EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<SourceType>::infinity()), std::numeric_limits<TargetType>::max()); |
226 | EXPECT_EQ(clampTo<TargetType>(-std::numeric_limits<SourceType>::infinity()), -std::numeric_limits<TargetType>::max()); |
227 | } |
228 | |
229 | TEST(WTF, clampFloatingPointToFloatingPoint) |
230 | { |
231 | testClampFloatingPointToFloatingPoint<float, float>(); |
232 | testClampFloatingPointToFloatingPoint<double, double>(); |
233 | |
234 | testClampFloatingPointToFloatingPoint<double, float>(); |
235 | testClampFloatingPointToFloatingPoint<float, double>(); |
236 | |
237 | // Large double into smaller float. |
238 | EXPECT_EQ(clampTo<float>(static_cast<double>(std::numeric_limits<float>::max())), std::numeric_limits<float>::max()); |
239 | EXPECT_EQ(clampTo<float>(-static_cast<double>(std::numeric_limits<float>::max())), -std::numeric_limits<float>::max()); |
240 | EXPECT_EQ(clampTo<float>(static_cast<double>(std::numeric_limits<float>::max()) + 1), std::numeric_limits<float>::max()); |
241 | EXPECT_EQ(clampTo<float>(-static_cast<double>(std::numeric_limits<float>::max()) - 1), -std::numeric_limits<float>::max()); |
242 | EXPECT_EQ(clampTo<float>(std::numeric_limits<double>::max()), std::numeric_limits<float>::max()); |
243 | EXPECT_EQ(clampTo<float>(-std::numeric_limits<double>::max()), -std::numeric_limits<float>::max()); |
244 | |
245 | float floatEspilon = std::numeric_limits<float>::epsilon(); |
246 | double doubleEspilon = std::numeric_limits<double>::epsilon(); |
247 | EXPECT_EQ(clampTo<float>(static_cast<double>(std::numeric_limits<float>::max()) + doubleEspilon), std::numeric_limits<float>::max()); |
248 | EXPECT_EQ(clampTo<float>(static_cast<double>(std::numeric_limits<float>::max()) - doubleEspilon), std::numeric_limits<float>::max()); |
249 | EXPECT_EQ(clampTo<float>(static_cast<double>(std::numeric_limits<float>::max()) + floatEspilon), std::numeric_limits<float>::max()); |
250 | EXPECT_EQ(clampTo<float>(static_cast<double>(std::numeric_limits<float>::max()) - floatEspilon), std::numeric_limits<float>::max() - floatEspilon); |
251 | } |
252 | #endif // !COMPILER(MSVC) |
253 | |
254 | template<typename FloatingPointType> |
255 | static void testClampFloatingPointToInteger() |
256 | { |
257 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(0)), 0); |
258 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(1)), 1); |
259 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(-1)), -1); |
260 | if (std::is_same<FloatingPointType, double>::value) |
261 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::max()) - 1.f), std::numeric_limits<int32_t>::max() - 1); |
262 | else |
263 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::max()) - 1.f), std::numeric_limits<int32_t>::max()); |
264 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::max())), std::numeric_limits<int32_t>::max()); |
265 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::max()) + 1.f), std::numeric_limits<int32_t>::max()); |
266 | |
267 | if (std::is_same<FloatingPointType, double>::value) |
268 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::min()) + 1.f), std::numeric_limits<int32_t>::min() + 1); |
269 | else |
270 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::min()) + 1.f), std::numeric_limits<int32_t>::min()); |
271 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::min())), std::numeric_limits<int32_t>::min()); |
272 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::min()) - 1.f), std::numeric_limits<int32_t>::min()); |
273 | |
274 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<uint32_t>::max())), std::numeric_limits<int32_t>::max()); |
275 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<uint32_t>::max()) + 1.f), std::numeric_limits<int32_t>::max()); |
276 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<uint32_t>::min())), 0.f); |
277 | |
278 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int64_t>::max())), std::numeric_limits<int32_t>::max()); |
279 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int64_t>::max()) + 1.f), std::numeric_limits<int32_t>::max()); |
280 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int64_t>::min())), std::numeric_limits<int32_t>::min()); |
281 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int64_t>::min()) - 1.f), std::numeric_limits<int32_t>::min()); |
282 | |
283 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<uint64_t>::max())), std::numeric_limits<int32_t>::max()); |
284 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<uint64_t>::max()) + 1.f), std::numeric_limits<int32_t>::max()); |
285 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<uint64_t>::min())), 0.f); |
286 | |
287 | FloatingPointType epsilon = std::numeric_limits<FloatingPointType>::epsilon(); |
288 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::max()) - epsilon), std::numeric_limits<int32_t>::max()); |
289 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::max()) + epsilon), std::numeric_limits<int32_t>::max()); |
290 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::min()) - epsilon), std::numeric_limits<int32_t>::min()); |
291 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<int32_t>::min()) + epsilon), std::numeric_limits<int32_t>::min()); |
292 | |
293 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(std::numeric_limits<FloatingPointType>::infinity())), std::numeric_limits<int32_t>::max()); |
294 | EXPECT_EQ(clampTo<int32_t>(static_cast<FloatingPointType>(-std::numeric_limits<FloatingPointType>::infinity())), std::numeric_limits<int32_t>::min()); |
295 | } |
296 | |
297 | TEST(WTF, clampFloatToInt) |
298 | { |
299 | testClampFloatingPointToInteger<float>(); |
300 | testClampFloatingPointToInteger<double>(); |
301 | |
302 | // 2**24 = 16777216, the largest integer representable exactly as float. |
303 | EXPECT_EQ(clampTo<int32_t>(static_cast<float>(16777215)), 16777215); |
304 | EXPECT_EQ(clampTo<int32_t>(static_cast<float>(16777216)), 16777216); |
305 | EXPECT_EQ(clampTo<int32_t>(static_cast<float>(16777217)), 16777216); |
306 | EXPECT_EQ(clampTo<int32_t>(static_cast<double>(16777216)), 16777216); |
307 | EXPECT_EQ(clampTo<int32_t>(static_cast<double>(16777217)), 16777217); |
308 | |
309 | EXPECT_EQ(clampTo<int16_t>(static_cast<float>(16777215)), std::numeric_limits<int16_t>::max()); |
310 | EXPECT_EQ(clampTo<int16_t>(static_cast<float>(16777216)), std::numeric_limits<int16_t>::max()); |
311 | EXPECT_EQ(clampTo<int16_t>(static_cast<float>(16777217)), std::numeric_limits<int16_t>::max()); |
312 | |
313 | // 2**53 = 9007199254740992, the largest integer representable exactly as double. |
314 | EXPECT_EQ(clampTo<uint64_t>(static_cast<double>(9007199254740991)), static_cast<uint64_t>(9007199254740991)); |
315 | EXPECT_EQ(clampTo<uint64_t>(static_cast<double>(9007199254740992)), static_cast<uint64_t>(9007199254740992)); |
316 | EXPECT_EQ(clampTo<uint64_t>(static_cast<double>(9007199254740993)), static_cast<uint64_t>(9007199254740992)); |
317 | |
318 | EXPECT_EQ(clampTo<int32_t>(static_cast<double>(9007199254740991)), std::numeric_limits<int32_t>::max()); |
319 | EXPECT_EQ(clampTo<int32_t>(static_cast<double>(9007199254740992)), std::numeric_limits<int32_t>::max()); |
320 | EXPECT_EQ(clampTo<int32_t>(static_cast<double>(9007199254740993)), std::numeric_limits<int32_t>::max()); |
321 | |
322 | // Test the double at the edge of max/min and max-1/min+1. |
323 | double intMax = static_cast<double>(std::numeric_limits<int32_t>::max()); |
324 | EXPECT_EQ(clampTo<int32_t>(intMax), std::numeric_limits<int32_t>::max()); |
325 | EXPECT_EQ(clampTo<int32_t>(std::nextafter(intMax, 0)), std::numeric_limits<int32_t>::max() - 1); |
326 | EXPECT_EQ(clampTo<int32_t>(std::nextafter(intMax, std::numeric_limits<double>::max())), std::numeric_limits<int32_t>::max()); |
327 | |
328 | EXPECT_EQ(clampTo<int32_t>(std::nextafter(intMax - 1., 0)), std::numeric_limits<int32_t>::max() - 2); |
329 | EXPECT_EQ(clampTo<int32_t>(intMax - 1), std::numeric_limits<int32_t>::max() - 1); |
330 | EXPECT_EQ(clampTo<int32_t>(std::nextafter(intMax - 1., std::numeric_limits<double>::max())), std::numeric_limits<int32_t>::max() - 1); |
331 | |
332 | double intMin = static_cast<double>(std::numeric_limits<int32_t>::min()); |
333 | EXPECT_EQ(clampTo<int32_t>(intMin), std::numeric_limits<int32_t>::min()); |
334 | EXPECT_EQ(clampTo<int32_t>(std::nextafter(intMin, 0)), std::numeric_limits<int32_t>::min() + 1); |
335 | EXPECT_EQ(clampTo<int32_t>(std::nextafter(intMin, -std::numeric_limits<double>::max())), std::numeric_limits<int32_t>::min()); |
336 | |
337 | EXPECT_EQ(clampTo<int32_t>(std::nextafter(intMin + 1, 0)), std::numeric_limits<int32_t>::min() + 2); |
338 | EXPECT_EQ(clampTo<int32_t>(intMin + 1), std::numeric_limits<int32_t>::min() + 1); |
339 | EXPECT_EQ(clampTo<int32_t>(std::nextafter(intMin + 1, -std::numeric_limits<double>::max())), std::numeric_limits<int32_t>::min() + 1); |
340 | } |
341 | |
342 | template<typename TargetType, typename SourceType> |
343 | static void testClampSameSignIntegers() |
344 | { |
345 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(0)), static_cast<TargetType>(0)); |
346 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(1)), static_cast<TargetType>(1)); |
347 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(-1)), std::numeric_limits<TargetType>::is_signed ? static_cast<TargetType>(-1) : std::numeric_limits<TargetType>::max()); |
348 | |
349 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::min())), std::numeric_limits<TargetType>::min()); |
350 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::max())), std::numeric_limits<TargetType>::max()); |
351 | |
352 | EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<SourceType>::min()), std::numeric_limits<TargetType>::min()); |
353 | EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<SourceType>::max()), std::numeric_limits<TargetType>::max()); |
354 | } |
355 | |
356 | TEST(WTF, clampSameSignIntegers) |
357 | { |
358 | testClampSameSignIntegers<char, char>(); |
359 | testClampSameSignIntegers<unsigned char, unsigned char>(); |
360 | testClampSameSignIntegers<char, int32_t>(); |
361 | testClampSameSignIntegers<unsigned char, uint32_t>(); |
362 | testClampSameSignIntegers<char, int64_t>(); |
363 | testClampSameSignIntegers<unsigned char, uint64_t>(); |
364 | |
365 | testClampSameSignIntegers<int32_t, int32_t>(); |
366 | testClampSameSignIntegers<uint32_t, uint32_t>(); |
367 | testClampSameSignIntegers<int32_t, int64_t>(); |
368 | testClampSameSignIntegers<uint32_t, uint64_t>(); |
369 | testClampSameSignIntegers<int16_t, int64_t>(); |
370 | testClampSameSignIntegers<uint16_t, uint64_t>(); |
371 | } |
372 | |
373 | template<typename TargetType, typename SourceType> |
374 | static void testClampUnsignedToSigned() |
375 | { |
376 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(0)), static_cast<TargetType>(0)); |
377 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(1)), static_cast<TargetType>(1)); |
378 | |
379 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::max()) - 1), std::numeric_limits<TargetType>::max() - 1); |
380 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::max())), std::numeric_limits<TargetType>::max()); |
381 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::max()) + 1), std::numeric_limits<TargetType>::max()); |
382 | EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<SourceType>::max()), std::numeric_limits<TargetType>::max()); |
383 | EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<SourceType>::max() - 1), std::numeric_limits<TargetType>::max()); |
384 | } |
385 | |
386 | TEST(WTF, clampUnsignedToSigned) |
387 | { |
388 | testClampUnsignedToSigned<char, unsigned char>(); |
389 | testClampUnsignedToSigned<char, uint32_t>(); |
390 | testClampUnsignedToSigned<int32_t, uint32_t>(); |
391 | testClampUnsignedToSigned<int64_t, uint64_t>(); |
392 | testClampUnsignedToSigned<int32_t, uint64_t>(); |
393 | testClampUnsignedToSigned<int16_t, uint32_t>(); |
394 | testClampUnsignedToSigned<int16_t, uint64_t>(); |
395 | } |
396 | |
397 | template<typename TargetType, typename SourceType> |
398 | static void testClampSignedToUnsigned() |
399 | { |
400 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(0)), static_cast<TargetType>(0)); |
401 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(1)), static_cast<TargetType>(1)); |
402 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(-1)), static_cast<TargetType>(0)); |
403 | |
404 | if (sizeof(TargetType) < sizeof(SourceType)) { |
405 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::min())), static_cast<TargetType>(0)); |
406 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::max()) - 1), std::numeric_limits<TargetType>::max() - 1); |
407 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::max())), std::numeric_limits<TargetType>::max()); |
408 | EXPECT_EQ(clampTo<TargetType>(static_cast<SourceType>(std::numeric_limits<TargetType>::max()) + 1), std::numeric_limits<TargetType>::max()); |
409 | } |
410 | |
411 | EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<SourceType>::min()), static_cast<TargetType>(0)); |
412 | if (sizeof(TargetType) < sizeof(SourceType)) |
413 | EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<SourceType>::max()), std::numeric_limits<TargetType>::max()); |
414 | else |
415 | EXPECT_EQ(clampTo<TargetType>(std::numeric_limits<SourceType>::max()), static_cast<TargetType>(std::numeric_limits<SourceType>::max())); |
416 | } |
417 | |
418 | TEST(WTF, clampSignedToUnsigned) |
419 | { |
420 | testClampSignedToUnsigned<unsigned char, char>(); |
421 | testClampSignedToUnsigned<unsigned char, int32_t>(); |
422 | testClampSignedToUnsigned<uint32_t, int32_t>(); |
423 | testClampSignedToUnsigned<uint64_t, int64_t>(); |
424 | testClampSignedToUnsigned<uint32_t, int64_t>(); |
425 | testClampSignedToUnsigned<uint16_t, int32_t>(); |
426 | testClampSignedToUnsigned<uint16_t, int64_t>(); |
427 | } |
428 | |
429 | TEST(WTF, roundUpToPowerOfTwo) |
430 | { |
431 | EXPECT_EQ(WTF::roundUpToPowerOfTwo(UINT32_MAX), 0U); |
432 | EXPECT_EQ(WTF::roundUpToPowerOfTwo(1U << 31), (1U << 31)); |
433 | EXPECT_EQ(WTF::roundUpToPowerOfTwo((1U << 31) + 1), 0U); |
434 | } |
435 | |
436 | TEST(WTF, clz) |
437 | { |
438 | EXPECT_EQ(WTF::clz<int32_t>(1), 31U); |
439 | EXPECT_EQ(WTF::clz<int32_t>(42), 26U); |
440 | EXPECT_EQ(WTF::clz<uint32_t>(static_cast<uint32_t>(-1)), 0U); |
441 | EXPECT_EQ(WTF::clz<uint32_t>(static_cast<uint32_t>(std::numeric_limits<int32_t>::min()) >> 1), 1U); |
442 | EXPECT_EQ(WTF::clz<uint32_t>(0), 32U); |
443 | |
444 | EXPECT_EQ(WTF::clz<int8_t>(42), 2U); |
445 | EXPECT_EQ(WTF::clz<int8_t>(3), 6U); |
446 | EXPECT_EQ(WTF::clz<uint8_t>(static_cast<uint8_t>(-1)), 0U); |
447 | EXPECT_EQ(WTF::clz<uint8_t>(0), 8U); |
448 | |
449 | EXPECT_EQ(WTF::clz<int64_t>(-1), 0U); |
450 | EXPECT_EQ(WTF::clz<int64_t>(1), 63U); |
451 | EXPECT_EQ(WTF::clz<int64_t>(3), 62U); |
452 | EXPECT_EQ(WTF::clz<uint64_t>(42), 58U); |
453 | EXPECT_EQ(WTF::clz<uint64_t>(0), 64U); |
454 | } |
455 | |
456 | TEST(WTF, ctz) |
457 | { |
458 | EXPECT_EQ(WTF::ctz<int32_t>(1), 0U); |
459 | EXPECT_EQ(WTF::ctz<int32_t>(42), 1U); |
460 | EXPECT_EQ(WTF::ctz<uint32_t>(static_cast<uint32_t>(-1)), 0U); |
461 | EXPECT_EQ(WTF::ctz<uint32_t>(static_cast<uint32_t>(std::numeric_limits<int32_t>::min()) >> 1), 30U); |
462 | EXPECT_EQ(WTF::ctz<uint32_t>(0), 32U); |
463 | |
464 | EXPECT_EQ(WTF::ctz<int8_t>(42), 1U); |
465 | EXPECT_EQ(WTF::ctz<int8_t>(3), 0U); |
466 | EXPECT_EQ(WTF::ctz<uint8_t>(static_cast<uint8_t>(-1)), 0U); |
467 | EXPECT_EQ(WTF::ctz<uint8_t>(0), 8U); |
468 | |
469 | EXPECT_EQ(WTF::ctz<int64_t>(static_cast<uint32_t>(-1)), 0U); |
470 | EXPECT_EQ(WTF::ctz<int64_t>(1), 0U); |
471 | EXPECT_EQ(WTF::ctz<int64_t>(3), 0U); |
472 | EXPECT_EQ(WTF::ctz<uint64_t>(42), 1U); |
473 | EXPECT_EQ(WTF::ctz<uint64_t>(0), 64U); |
474 | } |
475 | |
476 | TEST(WTF, getLSBSet) |
477 | { |
478 | EXPECT_EQ(WTF::getLSBSet<int32_t>(1), 0U); |
479 | EXPECT_EQ(WTF::getLSBSet<int32_t>(42), 1U); |
480 | EXPECT_EQ(WTF::getLSBSet<uint32_t>(static_cast<uint32_t>(-1)), 0U); |
481 | EXPECT_EQ(WTF::getLSBSet<uint32_t>(static_cast<uint32_t>(std::numeric_limits<int32_t>::min()) >> 1), 30U); |
482 | |
483 | EXPECT_EQ(WTF::getLSBSet<int8_t>(42), 1U); |
484 | EXPECT_EQ(WTF::getLSBSet<int8_t>(3), 0U); |
485 | EXPECT_EQ(WTF::getLSBSet<uint8_t>(static_cast<uint8_t>(-1)), 0U); |
486 | |
487 | EXPECT_EQ(WTF::getLSBSet<int64_t>(-1), 0U); |
488 | EXPECT_EQ(WTF::getLSBSet<int64_t>(1), 0U); |
489 | EXPECT_EQ(WTF::getLSBSet<int64_t>(3), 0U); |
490 | EXPECT_EQ(WTF::getLSBSet<uint64_t>(42), 1U); |
491 | } |
492 | |
493 | TEST(WTF, getMSBSet) |
494 | { |
495 | EXPECT_EQ(WTF::getMSBSet<int32_t>(1), 0U); |
496 | EXPECT_EQ(WTF::getMSBSet<int32_t>(42), 5U); |
497 | EXPECT_EQ(WTF::getMSBSet<uint32_t>(static_cast<uint32_t>(-1)), 31U); |
498 | EXPECT_EQ(WTF::getMSBSet<uint32_t>(static_cast<uint32_t>(std::numeric_limits<int32_t>::min()) >> 1), 30U); |
499 | |
500 | EXPECT_EQ(WTF::getMSBSet<int8_t>(42), 5U); |
501 | EXPECT_EQ(WTF::getMSBSet<int8_t>(3), 1U); |
502 | EXPECT_EQ(WTF::getMSBSet<uint8_t>(static_cast<uint8_t>(-1)), 7U); |
503 | |
504 | EXPECT_EQ(WTF::getMSBSet<int64_t>(-1), 63U); |
505 | EXPECT_EQ(WTF::getMSBSet<int64_t>(1), 0U); |
506 | EXPECT_EQ(WTF::getMSBSet<int64_t>(3), 1U); |
507 | EXPECT_EQ(WTF::getMSBSet<uint64_t>(42), 5U); |
508 | } |
509 | |
510 | TEST(WTF, clzConstexpr) |
511 | { |
512 | EXPECT_EQ(WTF::clzConstexpr<int32_t>(1), 31U); |
513 | EXPECT_EQ(WTF::clzConstexpr<int32_t>(42), 26U); |
514 | EXPECT_EQ(WTF::clzConstexpr<uint32_t>(static_cast<uint32_t>(-1)), 0U); |
515 | EXPECT_EQ(WTF::clzConstexpr<uint32_t>(static_cast<uint32_t>(std::numeric_limits<int32_t>::min()) >> 1), 1U); |
516 | EXPECT_EQ(WTF::clzConstexpr<uint32_t>(0), 32U); |
517 | |
518 | EXPECT_EQ(WTF::clzConstexpr<int8_t>(42), 2U); |
519 | EXPECT_EQ(WTF::clzConstexpr<int8_t>(3), 6U); |
520 | EXPECT_EQ(WTF::clzConstexpr<uint8_t>(static_cast<uint8_t>(-1)), 0U); |
521 | EXPECT_EQ(WTF::clzConstexpr<uint8_t>(0), 8U); |
522 | |
523 | EXPECT_EQ(WTF::clzConstexpr<int64_t>(-1), 0U); |
524 | EXPECT_EQ(WTF::clzConstexpr<int64_t>(1), 63U); |
525 | EXPECT_EQ(WTF::clzConstexpr<int64_t>(3), 62U); |
526 | EXPECT_EQ(WTF::clzConstexpr<uint64_t>(42), 58U); |
527 | EXPECT_EQ(WTF::clzConstexpr<uint64_t>(0), 64U); |
528 | } |
529 | |
530 | TEST(WTF, ctzConstexpr) |
531 | { |
532 | EXPECT_EQ(WTF::ctzConstexpr<int32_t>(1), 0U); |
533 | EXPECT_EQ(WTF::ctzConstexpr<int32_t>(42), 1U); |
534 | EXPECT_EQ(WTF::ctzConstexpr<uint32_t>(static_cast<uint32_t>(-1)), 0U); |
535 | EXPECT_EQ(WTF::ctzConstexpr<uint32_t>(static_cast<uint32_t>(std::numeric_limits<int32_t>::min()) >> 1), 30U); |
536 | EXPECT_EQ(WTF::ctzConstexpr<uint32_t>(0), 32U); |
537 | |
538 | EXPECT_EQ(WTF::ctzConstexpr<int8_t>(42), 1U); |
539 | EXPECT_EQ(WTF::ctzConstexpr<int8_t>(3), 0U); |
540 | EXPECT_EQ(WTF::ctzConstexpr<uint8_t>(static_cast<uint8_t>(-1)), 0U); |
541 | EXPECT_EQ(WTF::ctzConstexpr<uint8_t>(0), 8U); |
542 | |
543 | EXPECT_EQ(WTF::ctzConstexpr<int64_t>(static_cast<uint32_t>(-1)), 0U); |
544 | EXPECT_EQ(WTF::ctzConstexpr<int64_t>(1), 0U); |
545 | EXPECT_EQ(WTF::ctzConstexpr<int64_t>(3), 0U); |
546 | EXPECT_EQ(WTF::ctzConstexpr<uint64_t>(42), 1U); |
547 | EXPECT_EQ(WTF::ctzConstexpr<uint64_t>(0), 64U); |
548 | } |
549 | |
550 | TEST(WTF, getLSBSetConstexpr) |
551 | { |
552 | EXPECT_EQ(WTF::getLSBSetConstexpr<int32_t>(1), 0U); |
553 | EXPECT_EQ(WTF::getLSBSetConstexpr<int32_t>(42), 1U); |
554 | EXPECT_EQ(WTF::getLSBSetConstexpr<uint32_t>(static_cast<uint32_t>(-1)), 0U); |
555 | EXPECT_EQ(WTF::getLSBSetConstexpr<uint32_t>(static_cast<uint32_t>(std::numeric_limits<int32_t>::min()) >> 1), 30U); |
556 | |
557 | EXPECT_EQ(WTF::getLSBSetConstexpr<int8_t>(42), 1U); |
558 | EXPECT_EQ(WTF::getLSBSetConstexpr<int8_t>(3), 0U); |
559 | EXPECT_EQ(WTF::getLSBSetConstexpr<uint8_t>(static_cast<uint8_t>(-1)), 0U); |
560 | |
561 | EXPECT_EQ(WTF::getLSBSetConstexpr<int64_t>(-1), 0U); |
562 | EXPECT_EQ(WTF::getLSBSetConstexpr<int64_t>(1), 0U); |
563 | EXPECT_EQ(WTF::getLSBSetConstexpr<int64_t>(3), 0U); |
564 | EXPECT_EQ(WTF::getLSBSetConstexpr<uint64_t>(42), 1U); |
565 | } |
566 | |
567 | TEST(WTF, getMSBSetConstexpr) |
568 | { |
569 | EXPECT_EQ(WTF::getMSBSetConstexpr<int32_t>(1), 0U); |
570 | EXPECT_EQ(WTF::getMSBSetConstexpr<int32_t>(42), 5U); |
571 | EXPECT_EQ(WTF::getMSBSetConstexpr<uint32_t>(static_cast<uint32_t>(-1)), 31U); |
572 | EXPECT_EQ(WTF::getMSBSetConstexpr<uint32_t>(static_cast<uint32_t>(std::numeric_limits<int32_t>::min()) >> 1), 30U); |
573 | |
574 | EXPECT_EQ(WTF::getMSBSetConstexpr<int8_t>(42), 5U); |
575 | EXPECT_EQ(WTF::getMSBSetConstexpr<int8_t>(3), 1U); |
576 | EXPECT_EQ(WTF::getMSBSetConstexpr<uint8_t>(static_cast<uint8_t>(-1)), 7U); |
577 | |
578 | EXPECT_EQ(WTF::getMSBSetConstexpr<int64_t>(-1), 63U); |
579 | EXPECT_EQ(WTF::getMSBSetConstexpr<int64_t>(1), 0U); |
580 | EXPECT_EQ(WTF::getMSBSetConstexpr<int64_t>(3), 1U); |
581 | EXPECT_EQ(WTF::getMSBSetConstexpr<uint64_t>(42), 5U); |
582 | } |
583 | |
584 | } // namespace TestWebKitAPI |
585 | |