forked from suyu/suyu
common/swap: add swap template for enum
This commit is contained in:
parent
72c70d6808
commit
94bc48dd78
1 changed files with 52 additions and 0 deletions
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
|
@ -605,6 +607,44 @@ struct swap_double_t {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct swap_enum_t {
|
||||||
|
static_assert(std::is_enum_v<T>);
|
||||||
|
using base = std::underlying_type_t<T>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
swap_enum_t() = default;
|
||||||
|
swap_enum_t(const T& v) : value(swap(v)) {}
|
||||||
|
|
||||||
|
swap_enum_t& operator=(const T& v) {
|
||||||
|
value = swap(v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator T() const {
|
||||||
|
return swap(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit operator base() const {
|
||||||
|
return static_cast<base>(swap(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
T value{};
|
||||||
|
// clang-format off
|
||||||
|
using swap_t = std::conditional_t<
|
||||||
|
std::is_same_v<base, u16>, swap_16_t<u16>, std::conditional_t<
|
||||||
|
std::is_same_v<base, s16>, swap_16_t<s16>, std::conditional_t<
|
||||||
|
std::is_same_v<base, u32>, swap_32_t<u32>, std::conditional_t<
|
||||||
|
std::is_same_v<base, s32>, swap_32_t<s32>, std::conditional_t<
|
||||||
|
std::is_same_v<base, u64>, swap_64_t<u64>, std::conditional_t<
|
||||||
|
std::is_same_v<base, s64>, swap_64_t<s64>, void>>>>>>;
|
||||||
|
// clang-format on
|
||||||
|
static T swap(T x) {
|
||||||
|
return static_cast<T>(swap_t::swap(static_cast<base>(x)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#if COMMON_LITTLE_ENDIAN
|
#if COMMON_LITTLE_ENDIAN
|
||||||
using u16_le = u16;
|
using u16_le = u16;
|
||||||
using u32_le = u32;
|
using u32_le = u32;
|
||||||
|
@ -614,6 +654,9 @@ using s16_le = s16;
|
||||||
using s32_le = s32;
|
using s32_le = s32;
|
||||||
using s64_le = s64;
|
using s64_le = s64;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using enum_le = std::enable_if_t<std::is_enum_v<T>, T>;
|
||||||
|
|
||||||
using float_le = float;
|
using float_le = float;
|
||||||
using double_le = double;
|
using double_le = double;
|
||||||
|
|
||||||
|
@ -626,6 +669,9 @@ using s32_be = swap_struct_t<s32, swap_32_t<s32>>;
|
||||||
using u16_be = swap_struct_t<u16, swap_16_t<u16>>;
|
using u16_be = swap_struct_t<u16, swap_16_t<u16>>;
|
||||||
using s16_be = swap_struct_t<s16, swap_16_t<s16>>;
|
using s16_be = swap_struct_t<s16, swap_16_t<s16>>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using enum_be = swap_enum_t<T>;
|
||||||
|
|
||||||
using float_be = swap_struct_t<float, swap_float_t<float>>;
|
using float_be = swap_struct_t<float, swap_float_t<float>>;
|
||||||
using double_be = swap_struct_t<double, swap_double_t<double>>;
|
using double_be = swap_struct_t<double, swap_double_t<double>>;
|
||||||
#else
|
#else
|
||||||
|
@ -639,6 +685,9 @@ using s32_le = swap_struct_t<s32, swap_32_t<s32>>;
|
||||||
using u16_le = swap_struct_t<u16, swap_16_t<u16>>;
|
using u16_le = swap_struct_t<u16, swap_16_t<u16>>;
|
||||||
using s16_le = swap_struct_t<s16, swap_16_t<s16>>;
|
using s16_le = swap_struct_t<s16, swap_16_t<s16>>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using enum_le = swap_enum_t<T>;
|
||||||
|
|
||||||
using float_le = swap_struct_t<float, swap_float_t<float>>;
|
using float_le = swap_struct_t<float, swap_float_t<float>>;
|
||||||
using double_le = swap_struct_t<double, swap_double_t<double>>;
|
using double_le = swap_struct_t<double, swap_double_t<double>>;
|
||||||
|
|
||||||
|
@ -650,6 +699,9 @@ using s16_be = s16;
|
||||||
using s32_be = s32;
|
using s32_be = s32;
|
||||||
using s64_be = s64;
|
using s64_be = s64;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using enum_be = std::enable_if_t<std::is_enum_v<T>, T>;
|
||||||
|
|
||||||
using float_be = float;
|
using float_be = float;
|
||||||
using double_be = double;
|
using double_be = double;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue