Oxygen Engine
Modern C++ 3D Engine using OpenGL
Loading...
Searching...
No Matches
endian.h
1#ifndef OE_UTIL_ENDIAN_H
2#define OE_UTIL_ENDIAN_H
3
4#include <concepts>
5#include <span>
6#include <algorithm>
7#include <cstddef>
8
9#include <bit>
10
11namespace oe::util::endian
12{
16 [[nodiscard]] constexpr bool isLittleEndianHost() noexcept
17 {
18 return std::endian::native == std::endian::little;
19 }
20
24 [[nodiscard]] constexpr bool isBigEndianHost() noexcept
25 {
26 return std::endian::native == std::endian::big;
27 }
28
29 template <typename T>
30 concept NumericType = std::integral<T> || std::floating_point<T>;
31
35 template <std::integral T>
36 [[nodiscard]] constexpr T swapEndianess(const T& input) noexcept
37 {
38 #if defined(__cpp_lib_byteswap) && __cpp_lib_byteswap >= 202110L
39 // Note: C++23 byteswap only do integral types
40 return std::byteswap(input);
41 #else
42 T result;
43
44 std::span input_bytes = {reinterpret_cast<const std::byte*>(&input), sizeof(T)};
45 std::span result_bytes = {reinterpret_cast<std::byte*>(&result), sizeof(T)};
46
47 std::ranges::reverse_copy(input_bytes, result_bytes.begin());
48
49 return result;
50 #endif
51 }
52
56 template <std::floating_point T>
57 [[nodiscard]] constexpr T swapEndianess(const T& input) noexcept
58 {
59 T result;
60
61 std::span input_bytes = {reinterpret_cast<const std::byte*>(&input), sizeof(T)};
62 std::span result_bytes = {reinterpret_cast<std::byte*>(&result), sizeof(T)};
63
64 std::ranges::reverse_copy(input_bytes, result_bytes.begin());
65
66 return result;
67 }
68
74 template <NumericType T>
75 [[nodiscard]] constexpr T convertLittleEndianToHost(const T& data) noexcept
76 {
77 if (isBigEndianHost())
78 {
79 return swapEndianess(data);
80 }
81
82 return data;
83 }
84
90 template <NumericType T>
91 [[nodiscard]] constexpr T convertBigEndianToHost(const T& data) noexcept
92 {
93 if (isLittleEndianHost())
94 {
95 return swapEndianess(data);
96 }
97
98 return data;
99 }
100
106 template <NumericType T>
107 [[nodiscard]] constexpr T convertHostToLittleEndian(const T& data) noexcept
108 {
109 if (isBigEndianHost())
110 {
111 return swapEndianess(data);
112 }
113
114 return data;
115 }
116
122 template <NumericType T>
123 [[nodiscard]] constexpr T convertHostToBigEndian(const T& data) noexcept
124 {
125 if (isLittleEndianHost())
126 {
127 return swapEndianess(data);
128 }
129
130 return data;
131 }
132
133
134}
135#endif
Definition endian.h:30