summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWeiyi Wang <wwylele@gmail.com>2018-09-22 01:53:14 +0200
committerfearlessTobi <thm.frey@gmail.com>2019-02-06 17:21:15 +0100
commit94bc48dd783989a178ae8cb5956f50d990878a92 (patch)
treed1205cb5355b664cd220761235fddc2914307815
parentMerge pull request #2081 from ReinUsesLisp/lmem-64 (diff)
downloadyuzu-94bc48dd783989a178ae8cb5956f50d990878a92.tar
yuzu-94bc48dd783989a178ae8cb5956f50d990878a92.tar.gz
yuzu-94bc48dd783989a178ae8cb5956f50d990878a92.tar.bz2
yuzu-94bc48dd783989a178ae8cb5956f50d990878a92.tar.lz
yuzu-94bc48dd783989a178ae8cb5956f50d990878a92.tar.xz
yuzu-94bc48dd783989a178ae8cb5956f50d990878a92.tar.zst
yuzu-94bc48dd783989a178ae8cb5956f50d990878a92.zip
-rw-r--r--src/common/swap.h52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/common/swap.h b/src/common/swap.h
index 32af0b6ac..466096f58 100644
--- a/src/common/swap.h
+++ b/src/common/swap.h
@@ -17,6 +17,8 @@
#pragma once
+#include <type_traits>
+
#if defined(_MSC_VER)
#include <cstdlib>
#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
using u16_le = u16;
using u32_le = u32;
@@ -614,6 +654,9 @@ using s16_le = s16;
using s32_le = s32;
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 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 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 double_be = swap_struct_t<double, swap_double_t<double>>;
#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 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 double_le = swap_struct_t<double, swap_double_t<double>>;
@@ -650,6 +699,9 @@ using s16_be = s16;
using s32_be = s32;
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 double_be = double;