Toolbox snapshot
The Reactive C++ Toolbox
Loading...
Searching...
No Matches
Endian.hpp
Go to the documentation of this file.
1// The Reactive C++ Toolbox.
2// Copyright (C) 2013-2019 Swirly Cloud Limited
3// Copyright (C) 2022 Reactive Markets Limited
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17#ifndef TOOLBOX_NET_ENDIAN_HPP
18#define TOOLBOX_NET_ENDIAN_HPP
19
20#include <bit>
21#include <concepts>
22#include <cstdint>
23
24namespace toolbox {
25inline namespace net {
26
27constexpr std::uint16_t bswap(std::uint16_t n) noexcept
28{
29 return (n << 8) | (n >> 8);
30}
31
32constexpr std::int16_t bswap(std::int16_t n) noexcept
33{
34 return bswap(static_cast<std::uint16_t>(n));
35}
36
37constexpr std::uint32_t bswap(std::uint32_t n) noexcept
38{
39 return (n >> 24) | ((n >> 8) & 0xff00) | ((n << 8) & 0xff0000) | (n << 24);
40}
41
42constexpr std::int32_t bswap(std::int32_t n) noexcept
43{
44 return bswap(static_cast<std::uint32_t>(n));
45}
46
47constexpr std::uint64_t bswap(std::uint64_t n) noexcept
48{
49 const auto hi = std::uint64_t{bswap(static_cast<std::uint32_t>(n))} << 32;
50 return hi | bswap(static_cast<std::uint32_t>(n >> 32));
51}
52
53constexpr std::int64_t bswap(std::int64_t n) noexcept
54{
55 return bswap(static_cast<std::uint64_t>(n));
56}
57
58template <typename ValueT>
59 requires std::integral<ValueT>
60constexpr ValueT ntoh(ValueT n) noexcept
61{
62 if constexpr (std::endian::native == std::endian::little) {
63 return bswap(n);
64 } else {
65 return n;
66 }
67}
68
69template <typename ValueT>
70 requires std::integral<ValueT>
71constexpr ValueT hton(ValueT n) noexcept
72{
73 if constexpr (std::endian::native == std::endian::little) {
74 return bswap(n);
75 } else {
76 return n;
77 }
78}
79
80template <typename ValueT>
81 requires std::integral<ValueT>
82constexpr ValueT ltoh(ValueT n) noexcept
83{
84 if constexpr (std::endian::native == std::endian::little) {
85 return n;
86 } else {
87 return bswap(n);
88 }
89}
90
91template <typename ValueT>
92 requires std::integral<ValueT>
93constexpr ValueT htol(ValueT n) noexcept
94{
95 if constexpr (std::endian::native == std::endian::little) {
96 return n;
97 } else {
98 return bswap(n);
99 }
100}
101// Prevent corner case if mixed platform would use htol of big endian
102static_assert(std::endian::native == std::endian::little || std::endian::native == std::endian::big,
103 "Mixed endianness platforms are not supported");
104
105} // namespace net
106} // namespace toolbox
107
108#endif // TOOLBOX_NET_ENDIAN_HPP
constexpr ValueT hton(ValueT n) noexcept
Definition Endian.hpp:71
constexpr ValueT ltoh(ValueT n) noexcept
Definition Endian.hpp:82
constexpr ValueT ntoh(ValueT n) noexcept
Definition Endian.hpp:60
constexpr std::uint16_t bswap(std::uint16_t n) noexcept
Definition Endian.hpp:27
constexpr ValueT htol(ValueT n) noexcept
Definition Endian.hpp:93
constexpr auto bind() noexcept
Definition Slot.hpp:92