This repository has been archived by the owner on Jan 6, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbyteswap.hpp
74 lines (59 loc) · 2.35 KB
/
byteswap.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#ifndef IXM_BYTESWAP_HPP
#define IXM_BYTESWAP_HPP
#include <type_traits>
#include <cstdint>
#define IXM_IS_CONSTEXPR(...) noexcept(ixm::impl::is_constexpr(__VA_ARGS__))
namespace ixm {
inline namespace r0 {
namespace impl {
template <class T> constexpr void is_constexpr(T&& t) { }
template <class T>
constexpr auto as_unsigned (T value) noexcept {
return static_cast<std::make_unsigned_t<T>>(value);
}
#if defined(_MSC_VER)
inline auto bswap (std::uint64_t v) noexcept { return _byteswap_uint64(v); }
inline auto bswap (std::uint32_t v) noexcept { return _byteswap_ulong(v); }
inline auto bswap (std::uint16_t v) noexcept { return _byteswap_ushort(v); }
constexpr auto const_bswap (std::uint64_t v) noexcept {
return ((v & UINT64_C(0x0000'0000'0000'00FF)) << 56) |
((v & UINT64_C(0x0000'0000'0000'FF00)) << 40) |
((v & UINT64_C(0x0000'0000'00FF'0000)) << 24) |
((v & UINT64_C(0x0000'0000'FF00'0000)) << 8) |
((v & UINT64_C(0x0000'00FF'0000'0000)) >> 8) |
((v & UINT64_C(0x0000'FF00'0000'0000)) >> 24) |
((v & UINT64_C(0x00FF'0000'0000'0000)) >> 40) |
((v & UINT64_C(0xFF00'0000'0000'0000)) >> 56);
}
constexpr auto const_bswap (std::uint32_t v) noexcept {
return ((v & UINT32_C(0x0000'00FF)) << 24) |
((v & UINT32_C(0x0000'FF00)) << 8) |
((v & UINT32_C(0x00FF'0000)) >> 8) |
((v & UINT32_C(0xFF00'0000)) >> 24);
}
constexpr auto const_bswap (std::uint16_t v) noexcept {
return ((v & UINT16_C(0x00FF)) << 8) |
((v & UINT16_C(0xFF00)) >> 8);
}
#else
constexpr auto bswap (std::uint64_t v) noexcept { return __builtin_bswap64(v); }
constexpr auto bswap (std::uint32_t v) noexcept { return __builtin_bswap32(v); }
constexpr auto bswap (std::uint16_t v) noexcept { return __builtin_bswap16(v); }
#endif /* defined(_MSC_VER) */
}}} /* namespace ixm::r0::impl */
namespace ixm {
inline namespace r0 {
template <
class IntegerType,
class=std::enable_if_t<std::is_integral_v<IntegerType>>
> constexpr IntegerType byteswap (IntegerType value) noexcept {
if constexpr (sizeof(IntegerType) == 1) { return value; }
#if defined(_MSC_VER)
if constexpr (IXM_IS_CONSTEXPR(value)) {
return impl::const_bswap(impl::as_unsigned(value));
}
#endif /* defined(_MSC_VER) */
return impl::bswap(impl::as_unsigned(value));
}
}} /* namespace ixm::r0 */
#endif /* IXM_BYTESWAP_HPP */