roo_io
API Documentation for roo_io
Loading...
Searching...
No Matches
load.h
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <cstring>
5#include <limits>
6
7#include "roo_io/base/byte.h"
10
11namespace roo_io {
12
13inline constexpr uint8_t LoadU8(const byte *source) {
14 return (uint8_t)(*source);
15}
16
17// Loads a big-endian unsigned 16-bit int from the specified memory address.
18inline constexpr uint16_t LoadBeU16(const byte *source) {
19 return ((uint8_t)source[0] << 8) | ((uint8_t)source[1] << 0);
20}
21
22// Loads a little-endian unsigned 16-bit int from the specified memory address.
23inline constexpr uint16_t LoadLeU16(const byte *source) {
24 return ((uint8_t)source[0] << 0) | ((uint8_t)source[1] << 8);
25}
26
27// Loads a big-endian unsigned 24-bit int from the specified memory address.
28inline constexpr uint32_t LoadBeU24(const byte *source) {
29 return ((uint8_t)source[0] << 16) | ((uint8_t)source[1] << 8) |
30 ((uint8_t)source[2] << 0);
31}
32
33// Loads a little-endian unsigned 24-bit int from the specified memory address.
34inline constexpr uint32_t LoadLeU24(const byte *source) {
35 return ((uint8_t)source[0] << 0) | ((uint8_t)source[1] << 8) |
36 ((uint8_t)source[2] << 16);
37}
38
39// Loads a big-endian unsigned 32-bit int from the specified memory address.
40inline constexpr uint32_t LoadBeU32(const byte *source) {
41 return ((uint8_t)source[0] << 24) | ((uint8_t)source[1] << 16) |
42 ((uint8_t)source[2] << 8) | ((uint8_t)source[3] << 0);
43}
44
45// Loads a little-endian unsigned 32-bit int from the specified memory address.
46inline constexpr uint32_t LoadLeU32(const byte *source) {
47 return ((uint8_t)source[0] << 0) | ((uint8_t)source[1] << 8) |
48 ((uint8_t)source[2] << 16) | ((uint8_t)source[3] << 24);
49}
50
51// Loads a big-endian unsigned 64-bit int from the specified memory address.
52inline constexpr uint64_t LoadBeU64(const byte *source) {
53 return (((uint64_t)LoadBeU32(source)) << 32) | LoadBeU32(source + 4);
54}
55
56// Loads a little-endian unsigned 64-bit int from the specified memory address.
57inline constexpr uint64_t LoadLeU64(const byte *source) {
58 return LoadLeU32(source) | (((uint64_t)LoadLeU32(source + 4)) << 32);
59}
60
61inline constexpr int8_t LoadS8(const byte *source) {
62 return (int8_t)LoadU8(source);
63}
64
65// Loads a big-endian signed 16-bit int from the specified memory address.
66inline constexpr int16_t LoadBeS16(const byte *source) {
67 return (int16_t)LoadBeU16(source);
68}
69
70// Loads a little-endian signed 16-bit int from the specified memory address.
71inline constexpr int16_t LoadLeS16(const byte *source) {
72 return (int16_t)LoadLeU16(source);
73}
74
75// Loads a big-endian signed 24-bit int from the specified memory address.
76inline constexpr int32_t LoadBeS24(const byte *source) {
77 return (int32_t)LoadBeU24(source) | ((((uint8_t)source[0] & 0x80) > 0) * 0xFF)
78 << 24;
79}
80
81// Loads a little-endian signed 24-bit int from the specified memory address.
82inline constexpr int32_t LoadLeS24(const byte *source) {
83 return (int32_t)LoadLeU24(source) | ((((uint8_t)source[3] & 0x80) > 0) * 0xFF)
84 << 24;
85}
86
87// Loads a big-endian signed 32-bit int from the specified memory address.
88inline constexpr int32_t LoadBeS32(const byte *source) {
89 return (int32_t)LoadBeU32(source);
90}
91
92// Loads a little-endian signed 32-bit int from the specified memory address.
93inline constexpr int32_t LoadLeS32(const byte *source) {
94 return (int32_t)LoadLeU32(source);
95}
96
97// Loads a big-endian signed 64-bit int from the specified memory address.
98inline constexpr int64_t LoadBeS64(const byte *source) {
99 return (int64_t)LoadBeU64(source);
100}
101
102// Loads a little-endian signed 64-bit int from the specified memory address.
103inline constexpr int64_t LoadLeS64(const byte *source) {
104 return (int64_t)LoadLeU64(source);
105}
106
107#if ROO_IO_IEEE754
108// Loads a big-endian IEEE754 float from the specified memory address.
109inline float LoadBeFloat(const byte *source) {
110 static_assert(sizeof(float) == sizeof(uint32_t),
111 "LoadBeFloat requires 32-bit float.");
112 static_assert(std::numeric_limits<float>::is_iec559,
113 "LoadBeFloat requires IEEE754 float.");
115 float value;
116 memcpy(&value, &bits, sizeof(value));
117 return value;
118}
119
120// Loads a little-endian IEEE754 float from the specified memory address.
121inline float LoadLeFloat(const byte *source) {
122 static_assert(sizeof(float) == sizeof(uint32_t),
123 "LoadLeFloat requires 32-bit float.");
124 static_assert(std::numeric_limits<float>::is_iec559,
125 "LoadLeFloat requires IEEE754 float.");
127 float value;
128 memcpy(&value, &bits, sizeof(value));
129 return value;
130}
131
132// Loads a big-endian IEEE754 double from the specified memory address.
133inline double LoadBeDouble(const byte *source) {
134 static_assert(sizeof(double) == sizeof(uint64_t),
135 "LoadBeDouble requires 64-bit double.");
136 static_assert(std::numeric_limits<double>::is_iec559,
137 "LoadBeDouble requires IEEE754 double.");
139 double value;
140 memcpy(&value, &bits, sizeof(value));
141 return value;
142}
143
144// Loads a little-endian IEEE754 double from the specified memory address.
145inline double LoadLeDouble(const byte *source) {
146 static_assert(sizeof(double) == sizeof(uint64_t),
147 "LoadLeDouble requires 64-bit double.");
148 static_assert(std::numeric_limits<double>::is_iec559,
149 "LoadLeDouble requires IEEE754 double.");
151 double value;
152 memcpy(&value, &bits, sizeof(value));
153 return value;
154}
155#endif // ROO_IO_IEEE754
156
157// Loads a platform-native (implementation-dependent) datum from the specified
158// memory address. T must be default-constructible and have trivial destructor.
159template <typename T>
160inline constexpr T LoadHostNative(const byte *source) {
161 T result;
162 memcpy(&result, (const byte *)source, sizeof(result));
163 return result;
164}
165
166// Variants that can be used in code templated on the byte order.
167
168// Loads an unsigned 16-bit int from the specified memory address.
169template <ByteOrder byte_order>
170inline constexpr uint16_t LoadU16(const byte *source);
171
172// Loads an unsigned 24-bit int from the specified memory address.
173template <ByteOrder byte_order>
174inline constexpr uint32_t LoadU24(const byte *source);
175
176// Loads an unsigned 32-bit int from the specified memory address.
177template <ByteOrder byte_order>
178inline constexpr uint32_t LoadU32(const byte *source);
179
180// Loads an unsigned 64-bit int from the specified memory address.
181template <ByteOrder byte_order>
182inline constexpr uint64_t LoadU64(const byte *source);
183
184// Loads a signed 16-bit int from the specified memory address.
185template <ByteOrder byte_order>
186inline constexpr int16_t LoadS16(const byte *source);
187
188// Loads a signed 24-bit int from the specified memory address.
189template <ByteOrder byte_order>
190inline constexpr int32_t LoadS24(const byte *source);
191
192// Loads a signed 32-bit int from the specified memory address.
193template <ByteOrder byte_order>
194inline constexpr int32_t LoadS32(const byte *source);
195
196// Loads a signed 64-bit int from the specified memory address.
197template <ByteOrder byte_order>
198inline constexpr int64_t LoadS64(const byte *source);
199
200#if ROO_IO_IEEE754
201// Loads an IEEE754 float from the specified memory address.
202template <ByteOrder byte_order>
203inline float LoadFloat(const byte *source);
204
205// Loads an IEEE754 double from the specified memory address.
206template <ByteOrder byte_order>
207inline double LoadDouble(const byte *source);
208#endif // ROO_IO_IEEE754
209
210// Variants that can be used in code templated on the storage type.
211
212// Loads a big-endian integer from the specified memory address.
213template <typename IntegerType>
214inline constexpr IntegerType LoadBeInteger(const byte *source);
215
216// Loads a little-endian integer from the specified memory address.
217template <typename IntegerType>
218inline constexpr IntegerType LoadLeInteger(const byte *source);
219
220// Variant that can be used in code templated on both the byte order and the
221// storage type.
222
223// Loads an integer from the specified memory address.
224template <ByteOrder byte_order, typename IntegerType>
225inline constexpr IntegerType LoadInteger(const byte *source);
226
227// Implementation details below.
228
229template <>
230inline constexpr uint16_t LoadU16<kBigEndian>(const byte *source) {
231 return LoadBeU16(source);
232}
233
234template <>
235inline constexpr uint16_t LoadU16<kLittleEndian>(const byte *source) {
236 return LoadLeU16(source);
237}
238
239template <>
240inline constexpr uint32_t LoadU24<kBigEndian>(const byte *source) {
241 return LoadBeU24(source);
242}
243
244template <>
245inline constexpr uint32_t LoadU24<kLittleEndian>(const byte *source) {
246 return LoadLeU24(source);
247}
248
249template <>
250inline constexpr uint32_t LoadU32<kBigEndian>(const byte *source) {
251 return LoadBeU32(source);
252}
253
254template <>
255inline constexpr uint32_t LoadU32<kLittleEndian>(const byte *source) {
256 return LoadLeU32(source);
257}
258
259template <>
260inline constexpr uint64_t LoadU64<kBigEndian>(const byte *source) {
261 return LoadBeU64(source);
262}
263
264template <>
265inline constexpr uint64_t LoadU64<kLittleEndian>(const byte *source) {
266 return LoadLeU64(source);
267}
268
269template <>
270inline constexpr int16_t LoadS16<kBigEndian>(const byte *source) {
271 return LoadBeS16(source);
272}
273
274template <>
275inline constexpr int16_t LoadS16<kLittleEndian>(const byte *source) {
276 return LoadLeS16(source);
277}
278
279template <>
280inline constexpr int32_t LoadS24<kBigEndian>(const byte *source) {
281 return LoadBeS24(source);
282}
283
284template <>
285inline constexpr int32_t LoadS24<kLittleEndian>(const byte *source) {
286 return LoadLeS24(source);
287}
288
289template <>
290inline constexpr int32_t LoadS32<kBigEndian>(const byte *source) {
291 return LoadBeS32(source);
292}
293
294template <>
295inline constexpr int32_t LoadS32<kLittleEndian>(const byte *source) {
296 return LoadLeS32(source);
297}
298
299template <>
300inline constexpr int64_t LoadS64<kBigEndian>(const byte *source) {
301 return LoadBeS64(source);
302}
303
304template <>
305inline constexpr int64_t LoadS64<kLittleEndian>(const byte *source) {
306 return LoadLeS64(source);
307}
308
309#if ROO_IO_IEEE754
310template <>
311inline float LoadFloat<kBigEndian>(const byte *source) {
312 return LoadBeFloat(source);
313}
314
315template <>
316inline float LoadFloat<kLittleEndian>(const byte *source) {
317 return LoadLeFloat(source);
318}
319
320template <>
321inline double LoadDouble<kBigEndian>(const byte *source) {
322 return LoadBeDouble(source);
323}
324
325template <>
326inline double LoadDouble<kLittleEndian>(const byte *source) {
327 return LoadLeDouble(source);
328}
329#endif // ROO_IO_IEEE754
330
331template <>
332inline constexpr uint8_t LoadInteger<kBigEndian, uint8_t>(const byte *source) {
333 return LoadU8(source);
334}
335
336template <>
338 const byte *source) {
339 return LoadU8(source);
340}
341
342template <>
344 const byte *source) {
345 return LoadBeU16(source);
346}
347
348template <>
350 const byte *source) {
351 return LoadLeU16(source);
352}
353
354template <>
356 const byte *source) {
357 return LoadBeU32(source);
358}
359
360template <>
362 const byte *source) {
363 return LoadLeU32(source);
364}
365
366template <>
368 const byte *source) {
369 return LoadBeU64(source);
370}
371
372template <>
374 const byte *source) {
375 return LoadLeU64(source);
376}
377
378template <>
379inline constexpr int8_t LoadInteger<kBigEndian, int8_t>(const byte *source) {
380 return (int8_t)*(const byte *)source;
381}
382
383template <>
384inline constexpr int8_t LoadInteger<kLittleEndian, int8_t>(const byte *source) {
385 return (int8_t)*(const byte *)source;
386}
387
388template <>
389inline constexpr int16_t LoadInteger<kBigEndian, int16_t>(const byte *source) {
390 return LoadBeS16(source);
391}
392
393template <>
395 const byte *source) {
396 return LoadLeS16(source);
397}
398
399template <>
400inline constexpr int32_t LoadInteger<kBigEndian, int32_t>(const byte *source) {
401 return LoadBeS32(source);
402}
403
404template <>
406 const byte *source) {
407 return LoadLeS32(source);
408}
409
410template <>
411inline constexpr int64_t LoadInteger<kBigEndian, int64_t>(const byte *source) {
412 return LoadBeS64(source);
413}
414
415template <>
417 const byte *source) {
418 return LoadLeS64(source);
419}
420
421template <>
422inline constexpr uint8_t LoadBeInteger<uint8_t>(const byte *source) {
423 return LoadU8(source);
424}
425
426template <>
427inline constexpr uint8_t LoadLeInteger<uint8_t>(const byte *source) {
428 return LoadU8(source);
429}
430
431template <>
432inline constexpr uint16_t LoadBeInteger<uint16_t>(const byte *source) {
433 return LoadBeU16(source);
434}
435
436template <>
437inline constexpr uint16_t LoadLeInteger<uint16_t>(const byte *source) {
438 return LoadLeU16(source);
439}
440
441template <>
442inline constexpr uint32_t LoadBeInteger<uint32_t>(const byte *source) {
443 return LoadBeU32(source);
444}
445
446template <>
447inline constexpr uint32_t LoadLeInteger<uint32_t>(const byte *source) {
448 return LoadLeU32(source);
449}
450
451template <>
452inline constexpr uint64_t LoadBeInteger<uint64_t>(const byte *source) {
453 return LoadBeU64(source);
454}
455
456template <>
457inline constexpr uint64_t LoadLeInteger<uint64_t>(const byte *source) {
458 return LoadLeU64(source);
459}
460
461template <>
462inline constexpr int8_t LoadBeInteger<int8_t>(const byte *source) {
463 return LoadS8(source);
464}
465
466template <>
467inline constexpr int8_t LoadLeInteger<int8_t>(const byte *source) {
468 return LoadS8(source);
469}
470
471template <>
472inline constexpr int16_t LoadBeInteger<int16_t>(const byte *source) {
473 return LoadBeS16(source);
474}
475
476template <>
477inline constexpr int16_t LoadLeInteger<int16_t>(const byte *source) {
478 return LoadLeS16(source);
479}
480
481template <>
482inline constexpr int32_t LoadBeInteger<int32_t>(const byte *source) {
483 return LoadBeS32(source);
484}
485
486template <>
487inline constexpr int32_t LoadLeInteger<int32_t>(const byte *source) {
488 return LoadLeS32(source);
489}
490
491template <>
492inline constexpr int64_t LoadBeInteger<int64_t>(const byte *source) {
493 return LoadBeS64(source);
494}
495
496template <>
497inline constexpr int64_t LoadLeInteger<int64_t>(const byte *source) {
498 return LoadLeS64(source);
499}
500
501} // namespace roo_io
Definition byte.h:6
constexpr uint32_t LoadU32< kBigEndian >(const byte *source)
Definition load.h:250
constexpr int16_t LoadBeInteger< int16_t >(const byte *source)
Definition load.h:472
constexpr uint64_t LoadInteger< kBigEndian, uint64_t >(const byte *source)
Definition load.h:367
constexpr uint32_t LoadU32< kLittleEndian >(const byte *source)
Definition load.h:255
constexpr uint32_t LoadLeU32(const byte *source)
Definition load.h:46
constexpr int32_t LoadS24< kLittleEndian >(const byte *source)
Definition load.h:285
constexpr int64_t LoadBeInteger< int64_t >(const byte *source)
Definition load.h:492
constexpr uint8_t LoadU8(const byte *source)
Definition load.h:13
constexpr uint16_t LoadBeU16(const byte *source)
Definition load.h:18
constexpr int64_t LoadS64< kBigEndian >(const byte *source)
Definition load.h:300
constexpr uint16_t LoadBeInteger< uint16_t >(const byte *source)
Definition load.h:432
constexpr uint64_t LoadLeU64(const byte *source)
Definition load.h:57
constexpr uint16_t LoadU16(const byte *source)
constexpr uint64_t LoadLeInteger< uint64_t >(const byte *source)
Definition load.h:457
constexpr uint16_t LoadLeU16(const byte *source)
Definition load.h:23
constexpr uint16_t LoadU16< kBigEndian >(const byte *source)
Definition load.h:230
constexpr uint8_t LoadInteger< kLittleEndian, uint8_t >(const byte *source)
Definition load.h:337
roo::basic_string_view< CharT, Traits > basic_string_view
Definition string_view.h:8
constexpr uint32_t LoadLeInteger< uint32_t >(const byte *source)
Definition load.h:447
constexpr int64_t LoadInteger< kLittleEndian, int64_t >(const byte *source)
Definition load.h:416
constexpr int32_t LoadS32< kBigEndian >(const byte *source)
Definition load.h:290
constexpr int32_t LoadLeInteger< int32_t >(const byte *source)
Definition load.h:487
constexpr int8_t LoadInteger< kLittleEndian, int8_t >(const byte *source)
Definition load.h:384
constexpr uint32_t LoadU24(const byte *source)
constexpr uint8_t LoadInteger< kBigEndian, uint8_t >(const byte *source)
Definition load.h:332
constexpr uint8_t LoadLeInteger< uint8_t >(const byte *source)
Definition load.h:427
constexpr IntegerType LoadLeInteger(const byte *source)
constexpr uint32_t LoadU32(const byte *source)
constexpr int8_t LoadLeInteger< int8_t >(const byte *source)
Definition load.h:467
constexpr uint64_t LoadU64(const byte *source)
constexpr int32_t LoadS24< kBigEndian >(const byte *source)
Definition load.h:280
constexpr int16_t LoadS16< kBigEndian >(const byte *source)
Definition load.h:270
constexpr uint32_t LoadInteger< kBigEndian, uint32_t >(const byte *source)
Definition load.h:355
constexpr int64_t LoadS64(const byte *source)
constexpr int32_t LoadBeS32(const byte *source)
Definition load.h:88
constexpr uint64_t LoadBeU64(const byte *source)
Definition load.h:52
constexpr int64_t LoadBeS64(const byte *source)
Definition load.h:98
constexpr int16_t LoadS16< kLittleEndian >(const byte *source)
Definition load.h:275
constexpr int8_t LoadBeInteger< int8_t >(const byte *source)
Definition load.h:462
constexpr uint32_t LoadBeU32(const byte *source)
Definition load.h:40
constexpr int16_t LoadLeInteger< int16_t >(const byte *source)
Definition load.h:477
constexpr int64_t LoadS64< kLittleEndian >(const byte *source)
Definition load.h:305
constexpr int32_t LoadLeS32(const byte *source)
Definition load.h:93
constexpr uint8_t LoadBeInteger< uint8_t >(const byte *source)
Definition load.h:422
constexpr uint64_t LoadInteger< kLittleEndian, uint64_t >(const byte *source)
Definition load.h:373
constexpr int16_t LoadLeS16(const byte *source)
Definition load.h:71
constexpr int8_t LoadS8(const byte *source)
Definition load.h:61
constexpr uint32_t LoadBeU24(const byte *source)
Definition load.h:28
constexpr uint32_t LoadLeU24(const byte *source)
Definition load.h:34
constexpr int32_t LoadS32< kLittleEndian >(const byte *source)
Definition load.h:295
constexpr uint32_t LoadU24< kBigEndian >(const byte *source)
Definition load.h:240
constexpr IntegerType LoadInteger(const byte *source)
constexpr uint16_t LoadInteger< kLittleEndian, uint16_t >(const byte *source)
Definition load.h:349
constexpr int32_t LoadLeS24(const byte *source)
Definition load.h:82
constexpr int32_t LoadInteger< kLittleEndian, int32_t >(const byte *source)
Definition load.h:405
constexpr T LoadHostNative(const byte *source)
Definition load.h:160
constexpr uint32_t LoadInteger< kLittleEndian, uint32_t >(const byte *source)
Definition load.h:361
constexpr int8_t LoadInteger< kBigEndian, int8_t >(const byte *source)
Definition load.h:379
constexpr IntegerType LoadBeInteger(const byte *source)
constexpr int64_t LoadLeS64(const byte *source)
Definition load.h:103
constexpr int32_t LoadBeS24(const byte *source)
Definition load.h:76
constexpr uint32_t LoadBeInteger< uint32_t >(const byte *source)
Definition load.h:442
constexpr uint16_t LoadLeInteger< uint16_t >(const byte *source)
Definition load.h:437
constexpr uint64_t LoadBeInteger< uint64_t >(const byte *source)
Definition load.h:452
constexpr uint64_t LoadU64< kLittleEndian >(const byte *source)
Definition load.h:265
constexpr uint16_t LoadU16< kLittleEndian >(const byte *source)
Definition load.h:235
constexpr int32_t LoadS24(const byte *source)
constexpr int64_t LoadLeInteger< int64_t >(const byte *source)
Definition load.h:497
constexpr int16_t LoadInteger< kBigEndian, int16_t >(const byte *source)
Definition load.h:389
constexpr uint64_t LoadU64< kBigEndian >(const byte *source)
Definition load.h:260
constexpr uint16_t LoadInteger< kBigEndian, uint16_t >(const byte *source)
Definition load.h:343
constexpr int32_t LoadBeInteger< int32_t >(const byte *source)
Definition load.h:482
constexpr int16_t LoadS16(const byte *source)
constexpr int64_t LoadInteger< kBigEndian, int64_t >(const byte *source)
Definition load.h:411
constexpr int16_t LoadBeS16(const byte *source)
Definition load.h:66
constexpr uint32_t LoadU24< kLittleEndian >(const byte *source)
Definition load.h:245
constexpr int16_t LoadInteger< kLittleEndian, int16_t >(const byte *source)
Definition load.h:394
constexpr int32_t LoadInteger< kBigEndian, int32_t >(const byte *source)
Definition load.h:400
constexpr int32_t LoadS32(const byte *source)