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