• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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