M5Utility 0.0.7 git rev:ba71c71
Loading...
Searching...
No Matches
byteswap.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UTILITY_STL_BYTESWAP_HPP
11#define M5_UTILITY_STL_BYTESWAP_HPP
12
13#include <stdint.h>
14#include <type_traits>
15#include <cstring> // memcpy
16
17namespace m5 {
18namespace stl {
19
21template <typename U,
22 typename std::enable_if<sizeof(U) == 2 && std::is_unsigned<U>::value, std::nullptr_t>::type = nullptr>
23inline constexpr U bswap_fixed(U x) noexcept
24{
25 return static_cast<U>((static_cast<uint16_t>(x >> 8) & 0x00FFu) | (static_cast<uint16_t>(x << 8) & 0xFF00u));
26}
27
28template <typename U,
29 typename std::enable_if<sizeof(U) == 4 && std::is_unsigned<U>::value, std::nullptr_t>::type = nullptr>
30inline constexpr U bswap_fixed(U x) noexcept
31{
32 return static_cast<U>(((static_cast<uint32_t>(x) >> 24)) | ((static_cast<uint32_t>(x) >> 8) & 0x0000FF00u) |
33 ((static_cast<uint32_t>(x) << 8) & 0x00FF0000u) | ((static_cast<uint32_t>(x) << 24)));
34}
35
36template <typename U,
37 typename std::enable_if<sizeof(U) == 8 && std::is_unsigned<U>::value, std::nullptr_t>::type = nullptr>
38inline constexpr U bswap_fixed(U x) noexcept
39{
40 return static_cast<U>(
41 ((static_cast<uint64_t>(x) >> 56)) | ((static_cast<uint64_t>(x) >> 40) & 0x000000000000FF00ull) |
42 ((static_cast<uint64_t>(x) >> 24) & 0x0000000000FF0000ull) |
43 ((static_cast<uint64_t>(x) >> 8) & 0x00000000FF000000ull) |
44 ((static_cast<uint64_t>(x) << 8) & 0x000000FF00000000ull) |
45 ((static_cast<uint64_t>(x) << 24) & 0x0000FF0000000000ull) |
46 ((static_cast<uint64_t>(x) << 40) & 0x00FF000000000000ull) | ((static_cast<uint64_t>(x) << 56)));
47}
48
49#if defined(__SIZEOF_INT128__)
50template <typename U,
51 typename std::enable_if<sizeof(U) == 16 && std::is_unsigned<U>::value, std::nullptr_t>::type = nullptr>
52inline constexpr U bswap_fixed(U x) noexcept
53{
54 return ((static_cast<U>(bswap_fixed<uint64_t>(static_cast<uint64_t>(x))) << 64) |
55 static_cast<U>(bswap_fixed<uint64_t>(static_cast<uint64_t>(x >> 64))));
56}
57#endif
58
59template <typename U,
60 typename std::enable_if<sizeof(U) == 1 && std::is_unsigned<U>::value, std::nullptr_t>::type = nullptr>
61inline constexpr U bswap_fixed(U x) noexcept
62{
63 return x;
64}
65
66template <typename T, typename std::enable_if<(std::is_integral<T>::value || std::is_enum<T>::value),
67 std::nullptr_t>::type = nullptr>
68inline constexpr T byteswap_constexpr(T v) noexcept
69{
70 using U = typename std::make_unsigned<T>::type;
71 return static_cast<T>(bswap_fixed<U>(static_cast<U>(v)));
72}
74
76template <typename T, typename std::enable_if<(std::is_integral<T>::value || std::is_enum<T>::value),
77 std::nullptr_t>::type = nullptr>
78inline constexpr T byteswap(T v) noexcept
79{
80 return byteswap_constexpr(v);
81}
82
83// If the type is not integral , it is prohibited
84template <typename T, typename std::enable_if<!(std::is_integral<T>::value || std::is_enum<T>::value),
85 std::nullptr_t>::type = nullptr>
86T byteswap(T) = delete;
87
88} // namespace stl
89} // namespace m5
90
91#endif
constexpr T byteswap(T v) noexcept
byteswap for integral type
Definition byteswap.hpp:78
Top level namespace of M5.
Definition bit_segment.hpp:17
STL compatibility functions and classes.