util/ByteOrder: add class PackedLE64

This commit is contained in:
Max Kellermann 2023-03-12 20:23:58 +01:00
parent c472046cbb
commit f3ebaf8bdd

View File

@ -1,8 +1,7 @@
// SPDX-License-Identifier: BSD-2-Clause // SPDX-License-Identifier: BSD-2-Clause
// author: Max Kellermann <max.kellermann@gmail.com> // author: Max Kellermann <max.kellermann@gmail.com>
#ifndef BYTE_ORDER_HXX #pragma once
#define BYTE_ORDER_HXX
#include <cstdint> #include <cstdint>
@ -470,4 +469,54 @@ public:
static_assert(sizeof(PackedLE32) == sizeof(uint32_t), "Wrong size"); static_assert(sizeof(PackedLE32) == sizeof(uint32_t), "Wrong size");
static_assert(alignof(PackedLE32) == 1, "Wrong alignment"); static_assert(alignof(PackedLE32) == 1, "Wrong alignment");
#endif /**
* A packed little-endian 64 bit integer.
*/
class PackedLE64 {
uint8_t a, b, c, d, e, f, g, h;
public:
PackedLE64() = default;
constexpr PackedLE64(uint64_t src) noexcept
:a(uint8_t(src)),
b(uint8_t(src >> 8)),
c(uint8_t(src >> 16)),
d(uint8_t(src >> 24)),
e(uint8_t(src >> 32)),
f(uint8_t(src >> 40)),
g(uint8_t(src >> 48)),
h(uint8_t(src >> 56)) {}
/**
* Construct an instance from an integer which is already
* little-endian.
*/
static constexpr auto FromLE(uint64_t src) noexcept {
union {
uint64_t in;
PackedLE64 out;
} u{src};
return u.out;
}
constexpr operator uint64_t() const noexcept {
return uint64_t(a) | (uint64_t(b) << 8) |
(uint64_t(c) << 16) | (uint64_t(d) << 24) |
(uint64_t(e) << 32) | (uint64_t(f) << 40) |
(uint64_t(g) << 48) | (uint64_t(h) << 56);
}
/**
* Reads the raw, big-endian value.
*/
constexpr uint64_t raw() const noexcept {
uint64_t x = *this;
if (IsBigEndian())
x = ByteSwap64(x);
return x;
}
};
static_assert(sizeof(PackedLE64) == sizeof(uint64_t), "Wrong size");
static_assert(alignof(PackedLE64) == 1, "Wrong alignment");