Misc: use concepts instead of SFINAE

This commit is contained in:
oltolm
2025-06-26 12:47:00 +02:00
committed by Ty
parent ad6d0f7a6b
commit 0da84c2c69
9 changed files with 54 additions and 44 deletions

View File

@@ -7,9 +7,9 @@
// Template function for casting enumerations to their underlying type
template <typename Enumeration>
typename std::underlying_type<Enumeration>::type enum_cast(Enumeration E)
std::underlying_type_t<Enumeration> enum_cast(Enumeration E)
{
return static_cast<typename std::underlying_type<Enumeration>::type>(E);
return static_cast<typename std::underlying_type_t<Enumeration>>(E);
}
namespace detail
@@ -25,67 +25,67 @@ namespace detail
Enum value;
constexpr enum_bool_helper(Enum value): value(value) {}
constexpr operator Enum() const { return value; }
constexpr operator bool() const { return static_cast<bool>(static_cast<typename std::underlying_type<Enum>::type>(value)); }
constexpr operator bool() const { return static_cast<bool>(static_cast<std::underlying_type_t<Enum>>(value)); }
};
};
#define MARK_ENUM_AS_FLAGS(T) template<> struct detail::enum_is_flags<T> : public std::true_type {}
template <typename Enum>
constexpr typename std::enable_if<detail::enum_is_flags<Enum>::value, Enum>::type
operator|(Enum lhs, Enum rhs) noexcept
requires detail::enum_is_flags<Enum>::value
constexpr Enum operator|(Enum lhs, Enum rhs) noexcept
{
using underlying = typename std::underlying_type<Enum>::type;
using underlying = std::underlying_type_t<Enum>;
return static_cast<Enum>(static_cast<underlying>(lhs) | static_cast<underlying>(rhs));
}
template <typename Enum>
constexpr typename std::enable_if<detail::enum_is_flags<Enum>::value, detail::enum_bool_helper<Enum>>::type
operator&(Enum lhs, Enum rhs) noexcept
requires detail::enum_is_flags<Enum>::value
constexpr detail::enum_bool_helper<Enum> operator&(Enum lhs, Enum rhs) noexcept
{
using underlying = typename std::underlying_type<Enum>::type;
using underlying = std::underlying_type_t<Enum>;
return static_cast<Enum>(static_cast<underlying>(lhs) & static_cast<underlying>(rhs));
}
template <typename Enum>
constexpr typename std::enable_if<detail::enum_is_flags<Enum>::value, Enum>::type
operator^(Enum lhs, Enum rhs) noexcept
requires detail::enum_is_flags<Enum>::value
constexpr Enum operator^(Enum lhs, Enum rhs) noexcept
{
using underlying = typename std::underlying_type<Enum>::type;
using underlying = std::underlying_type_t<Enum>;
return static_cast<Enum>(static_cast<underlying>(lhs) ^ static_cast<underlying>(rhs));
}
template <typename Enum>
constexpr typename std::enable_if<detail::enum_is_flags<Enum>::value, Enum&>::type
operator|=(Enum& lhs, Enum rhs) noexcept
requires detail::enum_is_flags<Enum>::value
constexpr Enum& operator|=(Enum& lhs, Enum rhs) noexcept
{
return lhs = lhs | rhs;
}
template <typename Enum>
constexpr typename std::enable_if<detail::enum_is_flags<Enum>::value, Enum&>::type
operator&=(Enum& lhs, Enum rhs) noexcept
requires detail::enum_is_flags<Enum>::value
constexpr Enum& operator&=(Enum& lhs, Enum rhs) noexcept
{
return lhs = lhs & rhs;
}
template <typename Enum>
constexpr typename std::enable_if<detail::enum_is_flags<Enum>::value, Enum&>::type
operator^=(Enum& lhs, Enum rhs) noexcept
requires detail::enum_is_flags<Enum>::value
constexpr Enum& operator^=(Enum& lhs, Enum rhs) noexcept
{
return lhs = lhs ^ rhs;
}
template<typename Enum>
constexpr typename std::enable_if<detail::enum_is_flags<Enum>::value, bool>::type
operator!(Enum e) noexcept
template <typename Enum>
requires detail::enum_is_flags<Enum>::value
constexpr bool operator!(Enum e) noexcept
{
return !static_cast<typename std::underlying_type<Enum>::type>(e);
return !static_cast<std::underlying_type_t<Enum>>(e);
}
template<typename Enum>
constexpr typename std::enable_if<detail::enum_is_flags<Enum>::value, Enum>::type
operator~(Enum e) noexcept
template <typename Enum>
requires detail::enum_is_flags<Enum>::value
constexpr Enum operator~(Enum e) noexcept
{
return static_cast<Enum>(~static_cast<typename std::underlying_type<Enum>::type>(e));
return static_cast<Enum>(~static_cast<std::underlying_type_t<Enum>>(e));
}

View File

@@ -14,8 +14,8 @@
// Platform-specific includes
#if defined(_WIN32)
#include "RedtapeWindows.h"
static_assert(std::is_same<DWORD, unsigned long>::value, "DWORD is unsigned long");
static_assert(std::is_same<HRESULT, long>::value, "HRESULT is long");
static_assert(std::is_same_v<DWORD, unsigned long>, "DWORD is unsigned long");
static_assert(std::is_same_v<HRESULT, long>, "HRESULT is long");
#endif
Error::Error() = default;

View File

@@ -75,7 +75,8 @@ namespace StringUtil
}
/// Wrapper around std::from_chars
template <typename T, std::enable_if_t<std::is_integral<T>::value, bool> = true>
template <typename T>
requires std::is_integral_v<T>
inline std::optional<T> FromChars(const std::string_view str, int base = 10)
{
T value;
@@ -86,7 +87,8 @@ namespace StringUtil
return value;
}
template <typename T, std::enable_if_t<std::is_integral<T>::value, bool> = true>
template <typename T>
requires std::is_integral_v<T>
inline std::optional<T> FromChars(const std::string_view str, int base, std::string_view* endptr)
{
T value;
@@ -103,7 +105,8 @@ namespace StringUtil
return value;
}
template <typename T, std::enable_if_t<std::is_floating_point<T>::value, bool> = true>
template <typename T>
requires std::is_floating_point_v<T>
inline std::optional<T> FromChars(const std::string_view str)
{
T value;
@@ -114,7 +117,8 @@ namespace StringUtil
return value;
}
template <typename T, std::enable_if_t<std::is_floating_point<T>::value, bool> = true>
template <typename T>
requires std::is_floating_point_v<T>
inline std::optional<T> FromChars(const std::string_view str, std::string_view* endptr)
{
T value;
@@ -132,7 +136,8 @@ namespace StringUtil
}
/// Wrapper around std::to_chars
template <typename T, std::enable_if_t<std::is_integral<T>::value, bool> = true>
template <typename T>
requires std::is_integral_v<T>
inline std::string ToChars(T value, int base = 10)
{
// to_chars() requires macOS 10.15+.
@@ -154,7 +159,8 @@ namespace StringUtil
#endif
}
template <typename T, std::enable_if_t<std::is_floating_point<T>::value, bool> = true>
template <typename T>
requires std::is_floating_point_v<T>
inline std::string ToChars(T value)
{
// No to_chars() in older versions of libstdc++/libc++.

View File

@@ -44,7 +44,7 @@ namespace x86Emitter
template <typename T>
static __fi bool is_s8(T imm)
{
return (s8)imm == (typename std::make_signed<T>::type)imm;
return (s8)imm == (std::make_signed_t<T>)imm;
}
template <typename T>

View File

@@ -120,7 +120,8 @@ namespace GSDumpTypes
#undef DEF_GIFReg
// clang-format on
template <typename Output, typename Input, typename std::enable_if<sizeof(Input) == sizeof(Output), bool>::type = true>
template <typename Output, typename Input>
requires(sizeof(Input) == sizeof(Output))
static constexpr Output BitCast(Input input)
{
Output output;

View File

@@ -262,7 +262,7 @@ public:
template <typename T>
typename _unique_if<T>::_unique_array_unknown_bound make_unique(size_t count)
{
typedef typename std::remove_extent<T>::type Base;
typedef std::remove_extent_t<T> Base;
return UniquePtr<T>(make_array<Base>(count));
}

View File

@@ -25,8 +25,8 @@ class GSDrawScanlineCodeGenerator : public GSNewCodeGenerator
{
using XYm = DRAW_SCANLINE_VECTOR_REGISTER;
constexpr static bool isXmm = std::is_same<XYm, Xbyak::Xmm>::value;
constexpr static bool isYmm = std::is_same<XYm, Xbyak::Ymm>::value;
constexpr static bool isXmm = std::is_same_v<XYm, Xbyak::Xmm>;
constexpr static bool isYmm = std::is_same_v<XYm, Xbyak::Ymm>;
constexpr static int wordsize = 8;
constexpr static int vecsize = isXmm ? 16 : 32;
constexpr static int vecsizelog = isXmm ? 4 : 5;

View File

@@ -26,8 +26,8 @@ class GSSetupPrimCodeGenerator : public GSNewCodeGenerator
using Xmm = Xbyak::Xmm;
using Ymm = Xbyak::Ymm;
constexpr static bool isXmm = std::is_same<XYm, Xbyak::Xmm>::value;
constexpr static bool isYmm = std::is_same<XYm, Xbyak::Ymm>::value;
constexpr static bool isXmm = std::is_same_v<XYm, Xbyak::Xmm>;
constexpr static bool isYmm = std::is_same_v<XYm, Xbyak::Ymm>;
constexpr static int vecsize = isXmm ? 16 : 32;
constexpr static int dsize = isXmm ? 4 : 8;

View File

@@ -104,7 +104,8 @@ public:
u32 GetVersion() const { return m_version; }
/// Overload for integral or floating-point types. Writes bytes as-is.
template <typename T, std::enable_if_t<std::is_integral_v<T> || std::is_floating_point_v<T>, int> = 0>
template <typename T>
requires std::is_integral_v<T> || std::is_floating_point_v<T>
void Do(T* value_ptr)
{
if (m_mode == Mode::Read)
@@ -120,7 +121,8 @@ public:
}
/// Overload for enum types. Uses the underlying type.
template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
template <typename T>
requires std::is_enum_v<T>
void Do(T* value_ptr)
{
using TType = std::underlying_type_t<T>;
@@ -142,7 +144,8 @@ public:
}
/// Overload for POD types, such as structs.
template <typename T, std::enable_if_t<std::is_standard_layout_v<T> && std::is_trivial_v<T>, int> = 0>
template <typename T>
requires std::is_standard_layout_v<T> && std::is_trivial_v<T>
void DoPOD(T* value_ptr)
{
if (m_mode == Mode::Read)