types: Add constexpr endianness functions
Change-Id: I3ceff6cbd6d1991dc6131d266fa61dbf76595fdb
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/types.hpp b/src/types.hpp
index 79f1be4..75db6a4 100644
--- a/src/types.hpp
+++ b/src/types.hpp
@@ -6,6 +6,7 @@
#include <algorithm>
#include <array>
#include <chrono>
+#include <numeric>
#include <sdeventplus/clock.hpp>
#include <sdeventplus/utility/timer.hpp>
#include <string>
@@ -59,6 +60,91 @@
namespace detail
{
+template <typename T, uint8_t size = sizeof(T)>
+struct BswapAlign
+{
+ using type = T;
+};
+
+template <typename T>
+struct BswapAlign<T, 2>
+{
+ using type alignas(uint16_t) = T;
+};
+
+template <typename T>
+struct BswapAlign<T, 4>
+{
+ using type alignas(uint32_t) = T;
+};
+
+template <typename T>
+struct BswapAlign<T, 8>
+{
+ using type alignas(uint64_t) = T;
+};
+
+template <typename T>
+constexpr T bswapInt(typename BswapAlign<T>::type n) noexcept
+{
+ static_assert(std::is_trivially_copyable_v<T>);
+ if constexpr (sizeof(T) == 2)
+ {
+ reinterpret_cast<uint16_t&>(n) =
+ __builtin_bswap16(reinterpret_cast<uint16_t&>(n));
+ }
+ else if constexpr (sizeof(T) == 4)
+ {
+ reinterpret_cast<uint32_t&>(n) =
+ __builtin_bswap32(reinterpret_cast<uint32_t&>(n));
+ }
+ else if constexpr (sizeof(T) == 8)
+ {
+ reinterpret_cast<uint64_t&>(n) =
+ __builtin_bswap64(reinterpret_cast<uint64_t&>(n));
+ }
+ else
+ {
+ auto b = reinterpret_cast<std::byte*>(&n);
+ std::reverse(b, b + sizeof(n));
+ }
+ return n;
+}
+
+} // namespace detail
+
+template <typename T>
+constexpr T bswap(T n) noexcept
+{
+ return detail::bswapInt<T>(n);
+}
+
+template <typename T>
+constexpr T hton(T n) noexcept
+{
+ if constexpr (std::endian::native == std::endian::big)
+ {
+ return n;
+ }
+ else if constexpr (std::endian::native == std::endian::little)
+ {
+ return bswap(n);
+ }
+ else
+ {
+ static_assert(std::is_same_v<T, void>);
+ }
+}
+
+template <typename T>
+constexpr T ntoh(T n) noexcept
+{
+ return hton(n);
+}
+
+namespace detail
+{
+
template <typename T>
constexpr bool vcontains() noexcept
{