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
31namespace TestWebKitAPI {
32
33TEST(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
54TEST(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
74TEST(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
91TEST(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
112TEST(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
129TEST(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
149TEST(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
165TEST(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)
179template<typename TargetType, typename SourceType>
180static 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
229TEST(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
254template<typename FloatingPointType>
255static 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
297TEST(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
342template<typename TargetType, typename SourceType>
343static 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
356TEST(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
373template<typename TargetType, typename SourceType>
374static 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
386TEST(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
397template<typename TargetType, typename SourceType>
398static 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
418TEST(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
429TEST(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
436TEST(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
456TEST(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
476TEST(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
493TEST(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
510TEST(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
530TEST(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
550TEST(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
567TEST(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