Skip to content

Commit b8deba7

Browse files
committed
Move byte swapping methods using by endian wrapper into detail namespace
Hide the ugliness of OS macros away from viewers.
1 parent 528d8d0 commit b8deba7

File tree

4 files changed

+97
-58
lines changed

4 files changed

+97
-58
lines changed

build/win/libfly/libfly.vcxproj

+1
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@
228228
<ClInclude Include="..\..\..\fly\types\json\json.hpp" />
229229
<ClInclude Include="..\..\..\fly\types\json\json_exception.hpp" />
230230
<ClInclude Include="..\..\..\fly\types\json\types.hpp" />
231+
<ClInclude Include="..\..\..\fly\types\numeric\detail\byte_swap.hpp" />
231232
<ClInclude Include="..\..\..\fly\types\numeric\detail\endian_concepts.hpp" />
232233
<ClInclude Include="..\..\..\fly\types\numeric\detail\literal_parser.hpp" />
233234
<ClInclude Include="..\..\..\fly\types\numeric\endian.hpp" />

build/win/libfly/libfly.vcxproj.filters

+3
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,9 @@
283283
<ClInclude Include="..\..\..\fly\types\numeric\literals.hpp">
284284
<Filter>types\numeric</Filter>
285285
</ClInclude>
286+
<ClInclude Include="..\..\..\fly\types\numeric\detail\byte_swap.hpp">
287+
<Filter>types\numeric\detail</Filter>
288+
</ClInclude>
286289
<ClInclude Include="..\..\..\fly\types\numeric\detail\endian_concepts.hpp">
287290
<Filter>types\numeric\detail</Filter>
288291
</ClInclude>
+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#pragma once
2+
3+
#include "fly/fly.hpp"
4+
5+
#include <cstdint>
6+
7+
#if defined(FLY_LINUX)
8+
# include <byteswap.h>
9+
#elif defined(FLY_MACOS)
10+
# include <libkern/OSByteOrder.h>
11+
#elif defined(FLY_WINDOWS)
12+
# include "fly/types/numeric/literals.hpp"
13+
#else
14+
# error Unknown byte swapping includes.
15+
#endif
16+
17+
namespace fly::detail {
18+
19+
#if defined(FLY_LINUX)
20+
21+
constexpr std::uint16_t byte_swap(std::uint16_t value)
22+
{
23+
return __builtin_bswap16(value);
24+
}
25+
26+
constexpr std::uint32_t byte_swap(std::uint32_t value)
27+
{
28+
return __builtin_bswap32(value);
29+
}
30+
31+
constexpr std::uint64_t byte_swap(std::uint64_t value)
32+
{
33+
return __builtin_bswap64(value);
34+
}
35+
36+
#elif defined(FLY_MACOS)
37+
38+
constexpr std::uint16_t byte_swap(std::uint16_t value)
39+
{
40+
return OSSwapInt16(value);
41+
}
42+
43+
constexpr std::uint32_t byte_swap(std::uint32_t value)
44+
{
45+
return OSSwapInt32(value);
46+
}
47+
48+
constexpr std::uint64_t byte_swap(std::uint64_t value)
49+
{
50+
return OSSwapInt64(value);
51+
}
52+
53+
#elif defined(FLY_WINDOWS)
54+
55+
// Windows has _byteswap_ushort, _byteswap_ulong, and _byteswap_uint64, but they are non-constexpr.
56+
// So to allow endian swapping to be used at compile time, use custom byte swapping methods.
57+
58+
constexpr std::uint16_t byte_swap(std::uint16_t value)
59+
{
60+
using namespace fly::literals::numeric_literals;
61+
62+
return ((value & 0xff00_u16) >> 8) | ((value & 0x00ff_u16) << 8);
63+
}
64+
65+
constexpr std::uint32_t byte_swap(std::uint32_t value)
66+
{
67+
using namespace fly::literals::numeric_literals;
68+
69+
return (
70+
((value & 0xff00'0000_u32) >> 24) | ((value & 0x00ff'0000_u32) >> 8) |
71+
((value & 0x0000'ff00_u32) << 8) | ((value & 0x0000'00ff_u32) << 24));
72+
}
73+
74+
constexpr std::uint64_t byte_swap(std::uint64_t value)
75+
{
76+
using namespace fly::literals::numeric_literals;
77+
78+
return (
79+
((value & 0xff00'0000'0000'0000_u64) >> 56) | ((value & 0x00ff'0000'0000'0000_u64) >> 40) |
80+
((value & 0x0000'ff00'0000'0000_u64) >> 24) | ((value & 0x0000'00ff'0000'0000_u64) >> 8) |
81+
((value & 0x0000'0000'ff00'0000_u64) << 8) | ((value & 0x0000'0000'00ff'0000_u64) << 24) |
82+
((value & 0x0000'0000'0000'ff00_u64) << 40) | ((value & 0x0000'0000'0000'00ff_u64) << 56));
83+
}
84+
85+
#else
86+
# error Unknown byte swapping methods.
87+
#endif
88+
89+
} // namespace fly::detail

fly/types/numeric/endian.hpp

+4-58
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,12 @@
11
#pragma once
22

33
#include "fly/concepts/concepts.hpp"
4-
#include "fly/fly.hpp"
4+
#include "fly/types/numeric/detail/byte_swap.hpp"
55
#include "fly/types/numeric/detail/endian_concepts.hpp"
66

77
#include <bit>
88
#include <cstdint>
99

10-
#if defined(FLY_LINUX)
11-
# include <byteswap.h>
12-
#elif defined(FLY_MACOS)
13-
# include <libkern/OSByteOrder.h>
14-
#elif defined(FLY_WINDOWS)
15-
# include "fly/types/numeric/literals.hpp"
16-
#else
17-
# error Unknown byte swapping includes.
18-
#endif
19-
20-
#if defined(FLY_LINUX)
21-
# define byte_swap_16(b) __builtin_bswap16(b)
22-
# define byte_swap_32(b) __builtin_bswap32(b)
23-
# define byte_swap_64(b) __builtin_bswap64(b)
24-
#elif defined(FLY_MACOS)
25-
# define byte_swap_16(b) OSSwapInt16(b)
26-
# define byte_swap_32(b) OSSwapInt32(b)
27-
# define byte_swap_64(b) OSSwapInt64(b)
28-
#elif defined(FLY_WINDOWS)
29-
30-
// Windows has _byteswap_ushort, _byteswap_ulong, and _byteswap_uint64, but they are non-constexpr.
31-
// So to allow endian swapping to be used at compile time, use custom byte swapping methods.
32-
33-
constexpr std::uint16_t byte_swap_16(std::uint16_t value)
34-
{
35-
using namespace fly::literals::numeric_literals;
36-
37-
return ((value & 0xff00_u16) >> 8) | ((value & 0x00ff_u16) << 8);
38-
}
39-
40-
constexpr std::uint32_t byte_swap_32(std::uint32_t value)
41-
{
42-
using namespace fly::literals::numeric_literals;
43-
44-
return (
45-
((value & 0xff00'0000_u32) >> 24) | ((value & 0x00ff'0000_u32) >> 8) |
46-
((value & 0x0000'ff00_u32) << 8) | ((value & 0x0000'00ff_u32) << 24));
47-
}
48-
49-
constexpr std::uint64_t byte_swap_64(std::uint64_t value)
50-
{
51-
using namespace fly::literals::numeric_literals;
52-
53-
return (
54-
((value & 0xff00'0000'0000'0000_u64) >> 56) | ((value & 0x00ff'0000'0000'0000_u64) >> 40) |
55-
((value & 0x0000'ff00'0000'0000_u64) >> 24) | ((value & 0x0000'00ff'0000'0000_u64) >> 8) |
56-
((value & 0x0000'0000'ff00'0000_u64) << 8) | ((value & 0x0000'0000'00ff'0000_u64) << 24) |
57-
((value & 0x0000'0000'0000'ff00_u64) << 40) | ((value & 0x0000'0000'0000'00ff_u64) << 56));
58-
}
59-
60-
#else
61-
# error Unknown byte swapping methods.
62-
#endif
63-
6410
namespace fly {
6511

6612
/**
@@ -81,15 +27,15 @@ constexpr T endian_swap(T value)
8127
}
8228
else if constexpr (fly::SizeOfTypeIs<T, 2>)
8329
{
84-
return static_cast<T>(byte_swap_16(static_cast<std::uint16_t>(value)));
30+
return static_cast<T>(detail::byte_swap(static_cast<std::uint16_t>(value)));
8531
}
8632
else if constexpr (fly::SizeOfTypeIs<T, 4>)
8733
{
88-
return static_cast<T>(byte_swap_32(static_cast<std::uint32_t>(value)));
34+
return static_cast<T>(detail::byte_swap(static_cast<std::uint32_t>(value)));
8935
}
9036
else if constexpr (fly::SizeOfTypeIs<T, 8>)
9137
{
92-
return static_cast<T>(byte_swap_64(static_cast<std::uint64_t>(value)));
38+
return static_cast<T>(detail::byte_swap(static_cast<std::uint64_t>(value)));
9339
}
9440
}
9541

0 commit comments

Comments
 (0)