Skip to content

Commit c8837cd

Browse files
committed
Use C++20 concepts in endian operations
1 parent 2a5ccf3 commit c8837cd

File tree

4 files changed

+37
-12
lines changed

4 files changed

+37
-12
lines changed

build/win/libfly/libfly.vcxproj

+1
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@
227227
<ClInclude Include="..\..\..\fly\types\json\json_concepts.hpp" />
228228
<ClInclude Include="..\..\..\fly\types\json\json_exception.hpp" />
229229
<ClInclude Include="..\..\..\fly\types\json\json_types.hpp" />
230+
<ClInclude Include="..\..\..\fly\types\numeric\detail\endian_concepts.hpp" />
230231
<ClInclude Include="..\..\..\fly\types\numeric\detail\endian_traits.hpp" />
231232
<ClInclude Include="..\..\..\fly\types\numeric\detail\literal_parser.hpp" />
232233
<ClInclude Include="..\..\..\fly\types\numeric\endian.hpp" />

build/win/libfly/libfly.vcxproj.filters

+3
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,9 @@
280280
<ClInclude Include="..\..\..\fly\types\numeric\literals.hpp">
281281
<Filter>types\numeric</Filter>
282282
</ClInclude>
283+
<ClInclude Include="..\..\..\fly\types\numeric\detail\endian_concepts.hpp">
284+
<Filter>types\numeric\detail</Filter>
285+
</ClInclude>
283286
<ClInclude Include="..\..\..\fly\types\numeric\detail\endian_traits.hpp">
284287
<Filter>types\numeric\detail</Filter>
285288
</ClInclude>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#pragma once
2+
3+
#include "fly/traits/concepts.hpp"
4+
5+
#include <concepts>
6+
#include <type_traits>
7+
8+
namespace fly::detail {
9+
10+
/**
11+
* Concept that is satisfied if the given type is an integral type of a size supported by endian
12+
* operations.
13+
*/
14+
template <typename T>
15+
concept EndianInteger = requires
16+
{
17+
requires std::is_integral_v<std::remove_cvref_t<T>>;
18+
19+
requires !std::same_as<std::remove_cvref_t<T>, bool>;
20+
21+
requires fly::SizeOfTypeIs<T, 1> || fly::SizeOfTypeIs<T, 2> || fly::SizeOfTypeIs<T, 4> ||
22+
fly::SizeOfTypeIs<T, 8>;
23+
};
24+
25+
} // namespace fly::detail

fly/types/numeric/endian.hpp

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

33
#include "fly/fly.hpp"
4-
#include "fly/types/numeric/detail/endian_traits.hpp"
4+
#include "fly/traits/concepts.hpp"
5+
#include "fly/types/numeric/detail/endian_concepts.hpp"
56

67
#include <bit>
78
#include <cstdint>
8-
#include <type_traits>
99

1010
#if defined(FLY_LINUX)
1111
# include <byteswap.h>
@@ -72,26 +72,22 @@ namespace fly {
7272
*
7373
* @return The swapped value.
7474
*/
75-
template <typename T>
75+
template <detail::EndianInteger T>
7676
constexpr T endian_swap(T value)
7777
{
78-
static_assert(
79-
detail::EndianTraits::is_supported_integer_v<T>,
80-
"Value must be an integer type of size 1, 2, 4, or 8 bytes");
81-
82-
if constexpr (sizeof(T) == 1)
78+
if constexpr (fly::SizeOfTypeIs<T, 1>)
8379
{
8480
return value;
8581
}
86-
else if constexpr (sizeof(T) == 2)
82+
else if constexpr (fly::SizeOfTypeIs<T, 2>)
8783
{
8884
return static_cast<T>(byte_swap_16(static_cast<std::uint16_t>(value)));
8985
}
90-
else if constexpr (sizeof(T) == 4)
86+
else if constexpr (fly::SizeOfTypeIs<T, 4>)
9187
{
9288
return static_cast<T>(byte_swap_32(static_cast<std::uint32_t>(value)));
9389
}
94-
else if constexpr (sizeof(T) == 8)
90+
else if constexpr (fly::SizeOfTypeIs<T, 8>)
9591
{
9692
return static_cast<T>(byte_swap_64(static_cast<std::uint64_t>(value)));
9793
}
@@ -108,7 +104,7 @@ constexpr T endian_swap(T value)
108104
*
109105
* @return The swapped value.
110106
*/
111-
template <std::endian Endianness, typename T>
107+
template <std::endian Endianness, detail::EndianInteger T>
112108
constexpr T endian_swap_if_non_native(T value)
113109
{
114110
if constexpr (Endianness == std::endian::native)

0 commit comments

Comments
 (0)