diff --git a/Source/Core/Common/BitField.h b/Source/Core/Common/BitField.h index bbd40f5414..9a2e2032a0 100644 --- a/Source/Core/Common/BitField.h +++ b/Source/Core/Common/BitField.h @@ -114,12 +114,9 @@ */ #pragma pack(1) template ::type directly. - typename StorageType = typename std::conditional_t< - std::is_enum::value, std::underlying_type, std::enable_if>::type> + // StorageType is T for non-enum or the underlying-type for an enum. + typename StorageType = std::conditional_t, std::underlying_type, + std::type_identity>::type> struct BitField { private: @@ -212,12 +209,9 @@ class BitFieldArrayIterator; #pragma pack(1) template ::type directly. - typename StorageType = typename std::conditional_t< - std::is_enum::value, std::underlying_type, std::enable_if>::type> + // StorageType is T for non-enum or the underlying-type for an enum. + typename StorageType = std::conditional_t, std::underlying_type, + std::type_identity>::type> struct BitFieldArray { using Ref = BitFieldArrayRef; diff --git a/Source/Core/Common/BitUtils.h b/Source/Core/Common/BitUtils.h index 8b1b196c24..581305d345 100644 --- a/Source/Core/Common/BitUtils.h +++ b/Source/Core/Common/BitUtils.h @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -117,8 +116,8 @@ constexpr Result ExtractBits(const T src) noexcept template constexpr bool IsValidLowMask(const T mask) noexcept { - static_assert(std::is_integral::value, "Mask must be an integral type."); - static_assert(std::is_unsigned::value, "Signed masks can introduce hard to find bugs."); + static_assert(std::is_integral_v, "Mask must be an integral type."); + static_assert(std::is_unsigned_v, "Signed masks can introduce hard to find bugs."); // Can be efficiently determined without looping or bit counting. It's the counterpart // to https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2 @@ -138,11 +137,10 @@ public: explicit BitCastPtrType(PtrType* ptr) : m_ptr(ptr) {} // Enable operator= only for pointers to non-const data - template - inline typename std::enable_if() && !std::is_const()>::type - operator=(const S& source) + auto& operator=(const T& source) requires(!std::is_const_v) { std::memcpy(m_ptr, &source, sizeof(source)); + return *this; } inline operator T() const diff --git a/Source/Core/Common/ChunkFile.h b/Source/Core/Common/ChunkFile.h index ef9be1b7ce..7e48e6e913 100644 --- a/Source/Core/Common/ChunkFile.h +++ b/Source/Core/Common/ChunkFile.h @@ -32,7 +32,6 @@ #include "Common/EnumMap.h" #include "Common/Flag.h" #include "Common/Inline.h" -#include "Common/Logging/Log.h" // Wrapper class class PointerWrap @@ -195,13 +194,15 @@ public: DoArray(x.data(), static_cast(x.size())); } - template , int> = 0> + template + requires(std::is_trivially_copyable_v) void DoArray(T* x, u32 count) { DoVoid(x, count * sizeof(T)); } - template , int> = 0> + template + requires(!std::is_trivially_copyable_v) void DoArray(T* x, u32 count) { for (u32 i = 0; i < count; ++i) diff --git a/Source/Core/Common/Config/ConfigInfo.h b/Source/Core/Common/Config/ConfigInfo.h index be3d00108b..e8d904fae2 100644 --- a/Source/Core/Common/Config/ConfigInfo.h +++ b/Source/Core/Common/Config/ConfigInfo.h @@ -6,21 +6,14 @@ #include #include #include -#include #include #include "Common/CommonTypes.h" #include "Common/Config/Enums.h" +#include "Common/TypeUtils.h" namespace Config { -namespace detail -{ -// std::underlying_type may only be used with enum types, so make sure T is an enum type first. -template -using UnderlyingType = typename std::enable_if_t{}, std::underlying_type>::type; -} // namespace detail - struct Location { System system{}; @@ -54,8 +47,7 @@ public: // Make it easy to convert Info into Info> // so that enum settings can still easily work with code that doesn't care about the enum values. - template >::value>* = nullptr> + template Enum> Info(const Info& other) { *this = other; @@ -80,8 +72,7 @@ public: // Make it easy to convert Info into Info> // so that enum settings can still easily work with code that doesn't care about the enum values. - template >::value>* = nullptr> + template Enum> Info& operator=(const Info& other) { m_location = other.GetLocation(); diff --git a/Source/Core/Common/Config/Layer.h b/Source/Core/Common/Config/Layer.h index e82b411c29..3234cc0638 100644 --- a/Source/Core/Common/Config/Layer.h +++ b/Source/Core/Common/Config/Layer.h @@ -23,7 +23,8 @@ struct DefaultState namespace detail { -template ::value>* = nullptr> +template +requires(!Common::Enum) std::optional TryParse(const std::string& str_value) { T value; @@ -32,7 +33,7 @@ std::optional TryParse(const std::string& str_value) return value; } -template ::value>* = nullptr> +template std::optional TryParse(const std::string& str_value) { const auto result = TryParse>(str_value); diff --git a/Source/Core/Common/EnumFormatter.h b/Source/Core/Common/EnumFormatter.h index 2df7399fc7..77c25989ad 100644 --- a/Source/Core/Common/EnumFormatter.h +++ b/Source/Core/Common/EnumFormatter.h @@ -42,11 +42,10 @@ * constexpr formatter() : EnumFormatter(names) {} * }; */ -template +template class EnumFormatter { using T = decltype(last_member); - static_assert(std::is_enum_v); public: constexpr auto parse(fmt::format_parse_context& ctx) diff --git a/Source/Core/Common/EnumMap.h b/Source/Core/Common/EnumMap.h index 1eba9fe513..8f877a3a01 100644 --- a/Source/Core/Common/EnumMap.h +++ b/Source/Core/Common/EnumMap.h @@ -4,7 +4,6 @@ #pragma once #include -#include #include "Common/TypeUtils.h" @@ -15,11 +14,10 @@ namespace Common { // A type that allows lookup of values associated with an enum as the key. // Designed for enums whose numeric values start at 0 and increment continuously with few gaps. -template +template class EnumMap final { using T = decltype(last_member); - static_assert(std::is_enum_v); static constexpr size_t s_size = static_cast(last_member) + 1; using array_type = std::array; @@ -34,8 +32,9 @@ public: constexpr EnumMap& operator=(EnumMap&& other) = default; // Constructor that accepts exactly size Vs (enforcing that all must be specified). - template ::value>> - constexpr EnumMap(T... values) : m_array{static_cast(values)...} + template + constexpr EnumMap(T... values) requires(Common::IsNOf::value) + : m_array{static_cast(values)...} { } diff --git a/Source/Core/Common/SFMLHelper.h b/Source/Core/Common/SFMLHelper.h index cd8bb2303b..f3bf968823 100644 --- a/Source/Core/Common/SFMLHelper.h +++ b/Source/Core/Common/SFMLHelper.h @@ -3,26 +3,25 @@ #pragma once -#include - #include #include "Common/CommonTypes.h" +#include "Common/EnumUtils.h" #include "Common/Swap.h" +#include "Common/TypeUtils.h" sf::Packet& operator>>(sf::Packet& packet, Common::BigEndianValue& data); sf::Packet& operator>>(sf::Packet& packet, Common::BigEndianValue& data); sf::Packet& operator>>(sf::Packet& packet, Common::BigEndianValue& data); -template >* = nullptr> +template sf::Packet& operator<<(sf::Packet& packet, Enum e) { - using Underlying = std::underlying_type_t; - packet << static_cast(e); + packet << Common::ToUnderlying(e); return packet; } -template >* = nullptr> +template sf::Packet& operator>>(sf::Packet& packet, Enum& e) { using Underlying = std::underlying_type_t; diff --git a/Source/Core/Common/TypeUtils.h b/Source/Core/Common/TypeUtils.h index 0b1a2683eb..59a6393444 100644 --- a/Source/Core/Common/TypeUtils.h +++ b/Source/Core/Common/TypeUtils.h @@ -70,8 +70,8 @@ static_assert(!std::is_same_v, Bar>); // Template for checking if Types is count occurrences of T. template -struct IsNOf : std::integral_constant...> && - sizeof...(Ts) == count> +struct IsNOf : std::bool_constant...> && + sizeof...(Ts) == count> { };