v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
byte_conversions_unittest.cc
Go to the documentation of this file.
1// Copyright 2024 The Chromium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Slightly adapted for inclusion in V8.
6// Copyright 2025 the V8 project authors. All rights reserved.
7
9
10#include <array>
11#include <bit>
12#include <concepts>
13#include <cstdint>
14
15#include "testing/gtest/include/gtest/gtest.h"
16
18
19TEST(NumericsTest, FromNativeEndian) {
20 // The implementation of FromNativeEndian and FromLittleEndian assumes the
21 // native endian is little. If support of big endian is desired, compile-time
22 // branches will need to be added to the implementation, and the test results
23 // will differ there (they would match FromBigEndian in this test).
24 static_assert(std::endian::native == std::endian::little);
25 {
26 constexpr uint8_t bytes[] = {0x12u};
27 EXPECT_EQ(U8FromNativeEndian(bytes), 0x12u);
28 static_assert(std::same_as<uint8_t, decltype(U8FromNativeEndian(bytes))>);
29 static_assert(U8FromNativeEndian(bytes) == 0x12u);
30 }
31 {
32 constexpr uint8_t bytes[] = {0x12u, 0x34u};
33 EXPECT_EQ(U16FromNativeEndian(bytes), 0x34'12u);
34 static_assert(std::same_as<uint16_t, decltype(U16FromNativeEndian(bytes))>);
35 static_assert(U16FromNativeEndian(bytes) == 0x34'12u);
36 }
37 {
38 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u};
39 EXPECT_EQ(U32FromNativeEndian(bytes), 0x78'56'34'12u);
40 static_assert(std::same_as<uint32_t, decltype(U32FromNativeEndian(bytes))>);
41 static_assert(U32FromNativeEndian(bytes) == 0x78'56'34'12u);
42 }
43 {
44 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u,
45 0x90u, 0x12u, 0x34u, 0x56u};
46 EXPECT_EQ(U64FromNativeEndian(bytes), 0x56'34'12'90'78'56'34'12u);
47 static_assert(std::same_as<uint64_t, decltype(U64FromNativeEndian(bytes))>);
48 static_assert(U64FromNativeEndian(bytes) == 0x56'34'12'90'78'56'34'12u);
49 }
50
51 {
52 constexpr uint8_t bytes[] = {0x12u};
53 EXPECT_EQ(I8FromNativeEndian(bytes), 0x12);
54 static_assert(std::same_as<int8_t, decltype(I8FromNativeEndian(bytes))>);
55 static_assert(U8FromNativeEndian(bytes) == 0x12);
56 }
57 {
58 constexpr uint8_t bytes[] = {0x12u, 0x34u};
59 EXPECT_EQ(I16FromNativeEndian(bytes), 0x34'12);
60 static_assert(std::same_as<int16_t, decltype(I16FromNativeEndian(bytes))>);
61 static_assert(U16FromNativeEndian(bytes) == 0x34'12);
62 }
63 {
64 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u};
65 EXPECT_EQ(I32FromNativeEndian(bytes), 0x78'56'34'12);
66 static_assert(std::same_as<int32_t, decltype(I32FromNativeEndian(bytes))>);
67 static_assert(U32FromNativeEndian(bytes) == 0x78'56'34'12);
68 }
69 {
70 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u,
71 0x90u, 0x12u, 0x34u, 0x56u};
72 EXPECT_EQ(I64FromNativeEndian(bytes), 0x56'34'12'90'78'56'34'12);
73 static_assert(std::same_as<int64_t, decltype(I64FromNativeEndian(bytes))>);
74 static_assert(I64FromNativeEndian(bytes) == 0x56'34'12'90'78'56'34'12);
75 }
76
77 {
78 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u};
79 EXPECT_EQ(FloatFromNativeEndian(bytes), 1.73782443614e+34f);
80 EXPECT_EQ(std::bit_cast<uint32_t>(FloatFromNativeEndian(bytes)),
81 0x78'56'34'12u);
82 static_assert(std::same_as<float, decltype(FloatFromNativeEndian(bytes))>);
83 static_assert(FloatFromNativeEndian(bytes) == 1.73782443614e+34f);
84 static_assert(std::bit_cast<uint32_t>(FloatFromNativeEndian(bytes)) ==
85 0x78'56'34'12u);
86 }
87
88 {
89 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u,
90 0x90u, 0x12u, 0x34u, 0x56u};
91 EXPECT_EQ(DoubleFromNativeEndian(bytes),
92 1.84145159269283616391989849435e107);
93 EXPECT_EQ(std::bit_cast<uint64_t>(DoubleFromNativeEndian(bytes)),
94 0x56'34'12'90'78'56'34'12u);
95 static_assert(
96 std::same_as<double, decltype(DoubleFromNativeEndian(bytes))>);
97 static_assert(DoubleFromNativeEndian(bytes) ==
98 1.84145159269283616391989849435e107);
99 static_assert(std::bit_cast<uint64_t>(DoubleFromNativeEndian(bytes)) ==
100 0x56'34'12'90'78'56'34'12u);
101 }
102}
103
104TEST(NumericsTest, FromLittleEndian) {
105 // The implementation of FromNativeEndian and FromLittleEndian assumes the
106 // native endian is little. If support of big endian is desired, compile-time
107 // branches will need to be added to the implementation, and the test results
108 // will differ there (they would match FromBigEndian in this test).
109 static_assert(std::endian::native == std::endian::little);
110 {
111 constexpr uint8_t bytes[] = {0x12u};
112 EXPECT_EQ(U8FromLittleEndian(bytes), 0x12u);
113 static_assert(std::same_as<uint8_t, decltype(U8FromLittleEndian(bytes))>);
114 static_assert(U8FromLittleEndian(bytes) == 0x12u);
115 }
116 {
117 constexpr uint8_t bytes[] = {0x12u, 0x34u};
118 EXPECT_EQ(U16FromLittleEndian(bytes), 0x34'12u);
119 static_assert(std::same_as<uint16_t, decltype(U16FromLittleEndian(bytes))>);
120 static_assert(U16FromLittleEndian(bytes) == 0x34'12u);
121 }
122 {
123 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u};
124 EXPECT_EQ(U32FromLittleEndian(bytes), 0x78'56'34'12u);
125 static_assert(std::same_as<uint32_t, decltype(U32FromLittleEndian(bytes))>);
126 static_assert(U32FromLittleEndian(bytes) == 0x78'56'34'12u);
127 }
128 {
129 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u,
130 0x90u, 0x12u, 0x34u, 0x56u};
131 EXPECT_EQ(U64FromLittleEndian(bytes), 0x56'34'12'90'78'56'34'12u);
132 static_assert(std::same_as<uint64_t, decltype(U64FromLittleEndian(bytes))>);
133 static_assert(U64FromLittleEndian(bytes) == 0x56'34'12'90'78'56'34'12u);
134 }
135
136 {
137 constexpr uint8_t bytes[] = {0x12u};
138 EXPECT_EQ(I8FromLittleEndian(bytes), 0x12);
139 static_assert(std::same_as<int8_t, decltype(I8FromLittleEndian(bytes))>);
140 static_assert(I8FromLittleEndian(bytes) == 0x12);
141 }
142 {
143 constexpr uint8_t bytes[] = {0x12u, 0x34u};
144 EXPECT_EQ(I16FromLittleEndian(bytes), 0x34'12);
145 static_assert(std::same_as<int16_t, decltype(I16FromLittleEndian(bytes))>);
146 static_assert(I16FromLittleEndian(bytes) == 0x34'12);
147 }
148 {
149 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u};
150 EXPECT_EQ(I32FromLittleEndian(bytes), 0x78'56'34'12);
151 static_assert(std::same_as<int32_t, decltype(I32FromLittleEndian(bytes))>);
152 static_assert(I32FromLittleEndian(bytes) == 0x78'56'34'12);
153 }
154 {
155 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u,
156 0x90u, 0x12u, 0x34u, 0x56u};
157 EXPECT_EQ(I64FromLittleEndian(bytes), 0x56'34'12'90'78'56'34'12);
158 static_assert(std::same_as<int64_t, decltype(I64FromLittleEndian(bytes))>);
159 static_assert(I64FromLittleEndian(bytes) == 0x56'34'12'90'78'56'34'12);
160 }
161
162 {
163 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u};
164 EXPECT_EQ(FloatFromLittleEndian(bytes), 1.73782443614e+34f);
165 EXPECT_EQ(std::bit_cast<uint32_t>(FloatFromLittleEndian(bytes)),
166 0x78'56'34'12u);
167 static_assert(std::same_as<float, decltype(FloatFromLittleEndian(bytes))>);
168 static_assert(FloatFromLittleEndian(bytes) == 1.73782443614e+34f);
169 static_assert(std::bit_cast<uint32_t>(FloatFromLittleEndian(bytes)) ==
170 0x78'56'34'12u);
171 }
172
173 {
174 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u,
175 0x90u, 0x12u, 0x34u, 0x56u};
176 EXPECT_EQ(DoubleFromLittleEndian(bytes),
177 1.84145159269283616391989849435e107);
178 EXPECT_EQ(std::bit_cast<uint64_t>(DoubleFromLittleEndian(bytes)),
179 0x56'34'12'90'78'56'34'12u);
180 static_assert(
181 std::same_as<double, decltype(DoubleFromLittleEndian(bytes))>);
182 static_assert(DoubleFromLittleEndian(bytes) ==
183 1.84145159269283616391989849435e107);
184 static_assert(std::bit_cast<uint64_t>(DoubleFromLittleEndian(bytes)) ==
185 0x56'34'12'90'78'56'34'12u);
186 }
187}
188
189TEST(NumericsTest, FromBigEndian) {
190 // The implementation of FromNativeEndian and FromLittleEndian assumes the
191 // native endian is little. If support of big endian is desired, compile-time
192 // branches will need to be added to the implementation, and the test results
193 // will differ there (they would match FromLittleEndian in this test).
194 static_assert(std::endian::native == std::endian::little);
195 {
196 constexpr uint8_t bytes[] = {0x12u};
197 EXPECT_EQ(U8FromBigEndian(bytes), 0x12u);
198 static_assert(U8FromBigEndian(bytes) == 0x12u);
199 static_assert(std::same_as<uint8_t, decltype(U8FromBigEndian(bytes))>);
200 }
201 {
202 constexpr uint8_t bytes[] = {0x12u, 0x34u};
203 EXPECT_EQ(U16FromBigEndian(bytes), 0x12'34u);
204 static_assert(U16FromBigEndian(bytes) == 0x12'34u);
205 static_assert(std::same_as<uint16_t, decltype(U16FromBigEndian(bytes))>);
206 }
207 {
208 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u};
209 EXPECT_EQ(U32FromBigEndian(bytes), 0x12'34'56'78u);
210 static_assert(U32FromBigEndian(bytes) == 0x12'34'56'78u);
211 static_assert(std::same_as<uint32_t, decltype(U32FromBigEndian(bytes))>);
212 }
213 {
214 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u,
215 0x90u, 0x12u, 0x34u, 0x56u};
216 EXPECT_EQ(U64FromBigEndian(bytes), 0x12'34'56'78'90'12'34'56u);
217 static_assert(U64FromBigEndian(bytes) == 0x12'34'56'78'90'12'34'56u);
218 static_assert(std::same_as<uint64_t, decltype(U64FromBigEndian(bytes))>);
219 }
220
221 {
222 constexpr uint8_t bytes[] = {0x12u};
223 EXPECT_EQ(I8FromBigEndian(bytes), 0x12);
224 static_assert(I8FromBigEndian(bytes) == 0x12);
225 static_assert(std::same_as<int8_t, decltype(I8FromBigEndian(bytes))>);
226 }
227 {
228 constexpr uint8_t bytes[] = {0x12u, 0x34u};
229 EXPECT_EQ(I16FromBigEndian(bytes), 0x12'34);
230 static_assert(I16FromBigEndian(bytes) == 0x12'34);
231 static_assert(std::same_as<int16_t, decltype(I16FromBigEndian(bytes))>);
232 }
233 {
234 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u};
235 EXPECT_EQ(I32FromBigEndian(bytes), 0x12'34'56'78);
236 static_assert(I32FromBigEndian(bytes) == 0x12'34'56'78);
237 static_assert(std::same_as<int32_t, decltype(I32FromBigEndian(bytes))>);
238 }
239 {
240 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u,
241 0x90u, 0x12u, 0x34u, 0x56u};
242 EXPECT_EQ(I64FromBigEndian(bytes), 0x12'34'56'78'90'12'34'56);
243 static_assert(I64FromBigEndian(bytes) == 0x12'34'56'78'90'12'34'56);
244 static_assert(std::same_as<int64_t, decltype(I64FromBigEndian(bytes))>);
245 }
246
247 {
248 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u};
249 EXPECT_EQ(FloatFromBigEndian(bytes), 5.6904566139e-28f);
250 EXPECT_EQ(std::bit_cast<uint32_t>(FloatFromBigEndian(bytes)),
251 0x12'34'56'78u);
252 static_assert(std::same_as<float, decltype(FloatFromBigEndian(bytes))>);
253 static_assert(FloatFromBigEndian(bytes) == 5.6904566139e-28f);
254 static_assert(std::bit_cast<uint32_t>(FloatFromBigEndian(bytes)) ==
255 0x12'34'56'78u);
256 }
257 {
258 constexpr uint8_t bytes[] = {0x12u, 0x34u, 0x56u, 0x78u,
259 0x90u, 0x12u, 0x34u, 0x56u};
260 EXPECT_EQ(DoubleFromBigEndian(bytes), 5.62634909901491201382066931077e-221);
261 EXPECT_EQ(std::bit_cast<uint64_t>(DoubleFromBigEndian(bytes)),
262 0x12'34'56'78'90'12'34'56u);
263 static_assert(std::same_as<double, decltype(DoubleFromBigEndian(bytes))>);
264 static_assert(DoubleFromBigEndian(bytes) ==
265 5.62634909901491201382066931077e-221);
266 static_assert(std::bit_cast<uint64_t>(DoubleFromBigEndian(bytes)) ==
267 0x12'34'56'78'90'12'34'56u);
268 }
269}
270
271TEST(NumericsTest, ToNativeEndian) {
272 // The implementation of ToNativeEndian and ToLittleEndian assumes the native
273 // endian is little. If support of big endian is desired, compile-time
274 // branches will need to be added to the implementation, and the test results
275 // will differ there (they would match ToBigEndian in this test).
276 static_assert(std::endian::native == std::endian::little);
277 {
278 constexpr std::array<uint8_t, 1u> bytes = {0x12u};
279 constexpr auto val = uint8_t{0x12u};
280 EXPECT_EQ(U8ToNativeEndian(val), bytes);
281 static_assert(
282 std::same_as<std::array<uint8_t, 1u>, decltype(U8ToNativeEndian(val))>);
283 static_assert(U8ToNativeEndian(val) == bytes);
284 }
285 {
286 constexpr std::array<uint8_t, 2u> bytes = {0x12u, 0x34u};
287 constexpr auto val = uint16_t{0x34'12u};
288 EXPECT_EQ(U16ToNativeEndian(val), bytes);
289 static_assert(std::same_as<std::array<uint8_t, 2u>,
290 decltype(U16ToNativeEndian(val))>);
291 static_assert(U16ToNativeEndian(val) == bytes);
292 }
293 {
294 constexpr std::array<uint8_t, 4u> bytes = {0x12u, 0x34u, 0x56u, 0x78u};
295 constexpr auto val = uint32_t{0x78'56'34'12u};
296 EXPECT_EQ(U32ToNativeEndian(val), bytes);
297 static_assert(std::same_as<std::array<uint8_t, 4u>,
298 decltype(U32ToNativeEndian(val))>);
299 static_assert(U32ToNativeEndian(val) == bytes);
300 }
301 {
302 constexpr std::array<uint8_t, 8u> bytes = {0x12u, 0x34u, 0x56u, 0x78u,
303 0x90u, 0x12u, 0x34u, 0x56u};
304 constexpr auto val = uint64_t{0x56'34'12'90'78'56'34'12u};
305 EXPECT_EQ(U64ToNativeEndian(val), bytes);
306 static_assert(std::same_as<std::array<uint8_t, 8u>,
307 decltype(U64ToNativeEndian(val))>);
308 static_assert(U64ToNativeEndian(val) == bytes);
309 }
310
311 {
312 constexpr std::array<uint8_t, 1u> bytes = {0x12u};
313 constexpr auto val = int8_t{0x12};
314 EXPECT_EQ(I8ToNativeEndian(val), bytes);
315 static_assert(
316 std::same_as<std::array<uint8_t, 1u>, decltype(I8ToNativeEndian(val))>);
317 static_assert(I8ToNativeEndian(val) == bytes);
318 }
319 {
320 constexpr std::array<uint8_t, 2u> bytes = {0x12u, 0x34u};
321 constexpr auto val = int16_t{0x34'12};
322 EXPECT_EQ(I16ToNativeEndian(val), bytes);
323 static_assert(std::same_as<std::array<uint8_t, 2u>,
324 decltype(I16ToNativeEndian(val))>);
325 static_assert(I16ToNativeEndian(val) == bytes);
326 }
327 {
328 constexpr std::array<uint8_t, 4u> bytes = {0x12u, 0x34u, 0x56u, 0x78u};
329 constexpr auto val = int32_t{0x78'56'34'12};
330 EXPECT_EQ(I32ToNativeEndian(val), bytes);
331 static_assert(std::same_as<std::array<uint8_t, 4u>,
332 decltype(I32ToNativeEndian(val))>);
333 static_assert(I32ToNativeEndian(val) == bytes);
334 }
335 {
336 constexpr std::array<uint8_t, 8u> bytes = {0x12u, 0x34u, 0x56u, 0x78u,
337 0x90u, 0x12u, 0x34u, 0x56u};
338 constexpr auto val = int64_t{0x56'34'12'90'78'56'34'12};
339 EXPECT_EQ(I64ToNativeEndian(val), bytes);
340 static_assert(std::same_as<std::array<uint8_t, 8u>,
341 decltype(I64ToNativeEndian(val))>);
342 static_assert(I64ToNativeEndian(val) == bytes);
343 }
344
345 {
346 constexpr std::array<uint8_t, 4u> bytes = {0x12u, 0x34u, 0x56u, 0x78u};
347 constexpr float val = 1.73782443614e+34f;
348 EXPECT_EQ(FloatToNativeEndian(val), bytes);
349 static_assert(std::same_as<std::array<uint8_t, 4u>,
350 decltype(FloatToNativeEndian(val))>);
351 static_assert(FloatToNativeEndian(val) == bytes);
352 }
353
354 {
355 constexpr std::array<uint8_t, 8u> bytes = {0x12u, 0x34u, 0x56u, 0x78u,
356 0x90u, 0x12u, 0x34u, 0x56u};
357 constexpr double val = 1.84145159269283616391989849435e107;
358 EXPECT_EQ(DoubleToNativeEndian(val), bytes);
359 static_assert(std::same_as<std::array<uint8_t, 8u>,
360 decltype(DoubleToNativeEndian(val))>);
361 static_assert(DoubleToNativeEndian(val) == bytes);
362 }
363}
364
365TEST(NumericsTest, ToLittleEndian) {
366 // The implementation of ToNativeEndian and ToLittleEndian assumes the native
367 // endian is little. If support of big endian is desired, compile-time
368 // branches will need to be added to the implementation, and the test results
369 // will differ there (they would match ToBigEndian in this test).
370 static_assert(std::endian::native == std::endian::little);
371 {
372 constexpr std::array<uint8_t, 1u> bytes = {0x12u};
373 constexpr auto val = uint8_t{0x12u};
374 EXPECT_EQ(U8ToLittleEndian(val), bytes);
375 static_assert(
376 std::same_as<std::array<uint8_t, 1u>, decltype(U8ToLittleEndian(val))>);
377 static_assert(U8ToLittleEndian(val) == bytes);
378 }
379 {
380 constexpr std::array<uint8_t, 2u> bytes = {0x12u, 0x34u};
381 constexpr auto val = uint16_t{0x34'12u};
382 EXPECT_EQ(U16ToLittleEndian(val), bytes);
383 static_assert(std::same_as<std::array<uint8_t, 2u>,
384 decltype(U16ToLittleEndian(val))>);
385 static_assert(U16ToLittleEndian(val) == bytes);
386 }
387 {
388 constexpr std::array<uint8_t, 4u> bytes = {0x12u, 0x34u, 0x56u, 0x78u};
389 constexpr auto val = uint32_t{0x78'56'34'12u};
390 EXPECT_EQ(U32ToLittleEndian(val), bytes);
391 static_assert(std::same_as<std::array<uint8_t, 4u>,
392 decltype(U32ToLittleEndian(val))>);
393 static_assert(U32ToLittleEndian(val) == bytes);
394 }
395 {
396 constexpr std::array<uint8_t, 8u> bytes = {0x12u, 0x34u, 0x56u, 0x78u,
397 0x90u, 0x12u, 0x34u, 0x56u};
398 constexpr auto val = uint64_t{0x56'34'12'90'78'56'34'12u};
399 EXPECT_EQ(U64ToLittleEndian(val), bytes);
400 static_assert(std::same_as<std::array<uint8_t, 8u>,
401 decltype(U64ToLittleEndian(val))>);
402 static_assert(U64ToLittleEndian(val) == bytes);
403 }
404
405 {
406 constexpr std::array<uint8_t, 1u> bytes = {0x12u};
407 constexpr auto val = int8_t{0x12};
408 EXPECT_EQ(I8ToLittleEndian(val), bytes);
409 static_assert(
410 std::same_as<std::array<uint8_t, 1u>, decltype(I8ToLittleEndian(val))>);
411 static_assert(I8ToLittleEndian(val) == bytes);
412 }
413 {
414 constexpr std::array<uint8_t, 2u> bytes = {0x12u, 0x34u};
415 constexpr auto val = int16_t{0x34'12};
416 EXPECT_EQ(I16ToLittleEndian(val), bytes);
417 static_assert(std::same_as<std::array<uint8_t, 2u>,
418 decltype(I16ToLittleEndian(val))>);
419 static_assert(I16ToLittleEndian(val) == bytes);
420 }
421 {
422 constexpr std::array<uint8_t, 4u> bytes = {0x12u, 0x34u, 0x56u, 0x78u};
423 constexpr auto val = int32_t{0x78'56'34'12};
424 EXPECT_EQ(I32ToLittleEndian(val), bytes);
425 static_assert(std::same_as<std::array<uint8_t, 4u>,
426 decltype(I32ToLittleEndian(val))>);
427 static_assert(I32ToLittleEndian(val) == bytes);
428 }
429 {
430 constexpr std::array<uint8_t, 8u> bytes = {0x12u, 0x34u, 0x56u, 0x78u,
431 0x90u, 0x12u, 0x34u, 0x56u};
432 constexpr auto val = int64_t{0x56'34'12'90'78'56'34'12};
433 EXPECT_EQ(I64ToLittleEndian(val), bytes);
434 static_assert(std::same_as<std::array<uint8_t, 8u>,
435 decltype(I64ToLittleEndian(val))>);
436 static_assert(I64ToLittleEndian(val) == bytes);
437 }
438
439 {
440 constexpr std::array<uint8_t, 4u> bytes = {0x12u, 0x34u, 0x56u, 0x78u};
441 constexpr float val = 1.73782443614e+34f;
442 EXPECT_EQ(FloatToLittleEndian(val), bytes);
443 static_assert(std::same_as<std::array<uint8_t, 4u>,
444 decltype(FloatToLittleEndian(val))>);
445 static_assert(FloatToLittleEndian(val) == bytes);
446 }
447
448 {
449 constexpr std::array<uint8_t, 8u> bytes = {0x12u, 0x34u, 0x56u, 0x78u,
450 0x90u, 0x12u, 0x34u, 0x56u};
451 constexpr double val = 1.84145159269283616391989849435e107;
452 EXPECT_EQ(DoubleToLittleEndian(val), bytes);
453 static_assert(std::same_as<std::array<uint8_t, 8u>,
454 decltype(DoubleToLittleEndian(val))>);
455 static_assert(DoubleToLittleEndian(val) == bytes);
456 }
457}
458
459TEST(NumericsTest, ToBigEndian) {
460 // The implementation of ToBigEndian assumes the native endian is little. If
461 // support of big endian is desired, compile-time branches will need to be
462 // added to the implementation, and the test results will differ there (they
463 // would match ToLittleEndian in this test).
464 static_assert(std::endian::native == std::endian::little);
465 {
466 constexpr std::array<uint8_t, 1u> bytes = {0x12u};
467 constexpr auto val = uint8_t{0x12u};
468 EXPECT_EQ(U8ToBigEndian(val), bytes);
469 static_assert(
470 std::same_as<std::array<uint8_t, 1u>, decltype(U8ToBigEndian(val))>);
471 static_assert(U8ToBigEndian(val) == bytes);
472 }
473 {
474 constexpr std::array<uint8_t, 2u> bytes = {0x12u, 0x34u};
475 constexpr auto val = uint16_t{0x12'34u};
476 EXPECT_EQ(U16ToBigEndian(val), bytes);
477 static_assert(
478 std::same_as<std::array<uint8_t, 2u>, decltype(U16ToBigEndian(val))>);
479 static_assert(U16ToBigEndian(val) == bytes);
480 }
481 {
482 constexpr std::array<uint8_t, 4u> bytes = {0x12u, 0x34u, 0x56u, 0x78u};
483 constexpr auto val = uint32_t{0x12'34'56'78u};
484 EXPECT_EQ(U32ToBigEndian(val), bytes);
485 static_assert(
486 std::same_as<std::array<uint8_t, 4u>, decltype(U32ToBigEndian(val))>);
487 static_assert(U32ToBigEndian(val) == bytes);
488 }
489 {
490 constexpr std::array<uint8_t, 8u> bytes = {0x12u, 0x34u, 0x56u, 0x78u,
491 0x90u, 0x12u, 0x34u, 0x56u};
492 constexpr auto val = uint64_t{0x12'34'56'78'90'12'34'56u};
493 EXPECT_EQ(U64ToBigEndian(val), bytes);
494 static_assert(
495 std::same_as<std::array<uint8_t, 8u>, decltype(U64ToBigEndian(val))>);
496 static_assert(U64ToBigEndian(val) == bytes);
497 }
498
499 {
500 constexpr std::array<uint8_t, 1u> bytes = {0x12u};
501 constexpr auto val = int8_t{0x12u};
502 EXPECT_EQ(I8ToBigEndian(val), bytes);
503 static_assert(
504 std::same_as<std::array<uint8_t, 1u>, decltype(I8ToBigEndian(val))>);
505 static_assert(I8ToBigEndian(val) == bytes);
506 }
507 {
508 constexpr std::array<uint8_t, 2u> bytes = {0x12u, 0x34u};
509 constexpr auto val = int16_t{0x12'34u};
510 EXPECT_EQ(I16ToBigEndian(val), bytes);
511 static_assert(
512 std::same_as<std::array<uint8_t, 2u>, decltype(I16ToBigEndian(val))>);
513 static_assert(I16ToBigEndian(val) == bytes);
514 }
515 {
516 constexpr std::array<uint8_t, 4u> bytes = {0x12u, 0x34u, 0x56u, 0x78u};
517 constexpr auto val = int32_t{0x12'34'56'78u};
518 EXPECT_EQ(I32ToBigEndian(val), bytes);
519 static_assert(
520 std::same_as<std::array<uint8_t, 4u>, decltype(I32ToBigEndian(val))>);
521 static_assert(I32ToBigEndian(val) == bytes);
522 }
523 {
524 constexpr std::array<uint8_t, 8u> bytes = {0x12u, 0x34u, 0x56u, 0x78u,
525 0x90u, 0x12u, 0x34u, 0x56u};
526 constexpr auto val = int64_t{0x12'34'56'78'90'12'34'56u};
527 EXPECT_EQ(I64ToBigEndian(val), bytes);
528 static_assert(
529 std::same_as<std::array<uint8_t, 8u>, decltype(I64ToBigEndian(val))>);
530 static_assert(I64ToBigEndian(val) == bytes);
531 }
532
533 {
534 constexpr std::array<uint8_t, 4u> bytes = {0x12u, 0x34u, 0x56u, 0x78u};
535 constexpr float val = 5.6904566139e-28f;
536 EXPECT_EQ(FloatToBigEndian(val), bytes);
537 static_assert(
538 std::same_as<std::array<uint8_t, 4u>, decltype(FloatToBigEndian(val))>);
539 static_assert(FloatToBigEndian(val) == bytes);
540 }
541
542 {
543 constexpr std::array<uint8_t, 8u> bytes = {0x12u, 0x34u, 0x56u, 0x78u,
544 0x90u, 0x12u, 0x34u, 0x56u};
545 constexpr double val = 5.62634909901491201382066931077e-221;
546 EXPECT_EQ(DoubleToBigEndian(val), bytes);
547 static_assert(std::same_as<std::array<uint8_t, 8u>,
548 decltype(DoubleToBigEndian(val))>);
549 static_assert(DoubleToBigEndian(val) == bytes);
550 }
551}
552
553} // namespace v8::base::numerics
TEST(NumericsTest, FromNativeEndian)
constexpr uint8_t U8FromLittleEndian(std::span< const uint8_t, 1u > bytes)
constexpr float FloatFromLittleEndian(std::span< const uint8_t, 4u > bytes)
constexpr uint8_t U8FromNativeEndian(std::span< const uint8_t, 1u > bytes)
constexpr uint32_t U32FromBigEndian(std::span< const uint8_t, 4u > bytes)
constexpr double DoubleFromNativeEndian(std::span< const uint8_t, 8u > bytes)
constexpr std::array< uint8_t, 4u > FloatToLittleEndian(float val)
constexpr uint16_t U16FromLittleEndian(std::span< const uint8_t, 2u > bytes)
constexpr std::array< uint8_t, 4u > FloatToBigEndian(float val)
constexpr int32_t I32FromNativeEndian(std::span< const uint8_t, 4u > bytes)
constexpr std::array< uint8_t, 4u > U32ToBigEndian(uint32_t val)
constexpr uint64_t U64FromNativeEndian(std::span< const uint8_t, 8u > bytes)
constexpr std::array< uint8_t, 8u > DoubleToBigEndian(double val)
constexpr std::array< uint8_t, 2u > U16ToNativeEndian(uint16_t val)
constexpr std::array< uint8_t, 4u > U32ToNativeEndian(uint32_t val)
constexpr int32_t I32FromBigEndian(std::span< const uint8_t, 4u > bytes)
constexpr uint64_t U64FromLittleEndian(std::span< const uint8_t, 8u > bytes)
constexpr int64_t I64FromBigEndian(std::span< const uint8_t, 8u > bytes)
constexpr std::array< uint8_t, 8u > U64ToNativeEndian(uint64_t val)
constexpr std::array< uint8_t, 1u > I8ToBigEndian(int8_t val)
constexpr uint32_t U32FromLittleEndian(std::span< const uint8_t, 4u > bytes)
constexpr int16_t I16FromLittleEndian(std::span< const uint8_t, 2u > bytes)
constexpr std::array< uint8_t, 1u > U8ToNativeEndian(uint8_t val)
constexpr std::array< uint8_t, 2u > I16ToBigEndian(int16_t val)
constexpr std::array< uint8_t, 1u > I8ToNativeEndian(int8_t val)
constexpr int64_t I64FromLittleEndian(std::span< const uint8_t, 8u > bytes)
constexpr std::array< uint8_t, 1u > I8ToLittleEndian(int8_t val)
constexpr std::array< uint8_t, 8u > U64ToBigEndian(uint64_t val)
constexpr std::array< uint8_t, 4u > U32ToLittleEndian(uint32_t val)
constexpr std::array< uint8_t, 1u > U8ToBigEndian(uint8_t val)
constexpr int16_t I16FromBigEndian(std::span< const uint8_t, 2u > bytes)
constexpr std::array< uint8_t, 4u > I32ToBigEndian(int32_t val)
constexpr std::array< uint8_t, 4u > FloatToNativeEndian(float val)
constexpr std::array< uint8_t, 2u > I16ToNativeEndian(int16_t val)
constexpr std::array< uint8_t, 8u > DoubleToNativeEndian(double val)
constexpr std::array< uint8_t, 1u > U8ToLittleEndian(uint8_t val)
constexpr int8_t I8FromLittleEndian(std::span< const uint8_t, 1u > bytes)
constexpr std::array< uint8_t, 8u > I64ToBigEndian(int64_t val)
constexpr float FloatFromNativeEndian(std::span< const uint8_t, 4u > bytes)
constexpr int16_t I16FromNativeEndian(std::span< const uint8_t, 2u > bytes)
constexpr std::array< uint8_t, 8u > I64ToNativeEndian(int64_t val)
constexpr int8_t I8FromNativeEndian(std::span< const uint8_t, 1u > bytes)
constexpr uint64_t U64FromBigEndian(std::span< const uint8_t, 8u > bytes)
constexpr std::array< uint8_t, 8u > U64ToLittleEndian(uint64_t val)
constexpr double DoubleFromBigEndian(std::span< const uint8_t, 8u > bytes)
constexpr uint8_t U8FromBigEndian(std::span< const uint8_t, 1u > bytes)
constexpr float FloatFromBigEndian(std::span< const uint8_t, 4u > bytes)
constexpr int64_t I64FromNativeEndian(std::span< const uint8_t, 8u > bytes)
constexpr int8_t I8FromBigEndian(std::span< const uint8_t, 1u > bytes)
constexpr double DoubleFromLittleEndian(std::span< const uint8_t, 8u > bytes)
constexpr std::array< uint8_t, 4u > I32ToLittleEndian(int32_t val)
constexpr int32_t I32FromLittleEndian(std::span< const uint8_t, 4u > bytes)
constexpr std::array< uint8_t, 8u > DoubleToLittleEndian(double val)
constexpr std::array< uint8_t, 8u > I64ToLittleEndian(int64_t val)
constexpr uint16_t U16FromNativeEndian(std::span< const uint8_t, 2u > bytes)
constexpr std::array< uint8_t, 4u > I32ToNativeEndian(int32_t val)
constexpr std::array< uint8_t, 2u > U16ToLittleEndian(uint16_t val)
constexpr std::array< uint8_t, 2u > I16ToLittleEndian(int16_t val)
constexpr uint16_t U16FromBigEndian(std::span< const uint8_t, 2u > bytes)
constexpr std::array< uint8_t, 2u > U16ToBigEndian(uint16_t val)
constexpr uint32_t U32FromNativeEndian(std::span< const uint8_t, 4u > bytes)