diff options
| author | Jordan Woyak <jordan.woyak@gmail.com> | 2025-05-05 19:30:53 -0500 |
|---|---|---|
| committer | Jordan Woyak <jordan.woyak@gmail.com> | 2025-05-05 19:34:24 -0500 |
| commit | 2dc975fa923cfabcd0ee4459eb608219a72e4e02 (patch) | |
| tree | b11251616ef7581e5f5efdebf8587fff84f96e1d /Source/Core/Common | |
| parent | 210b5cbf66a8c1aa28cf95aff8985ea54138ef8b (diff) | |
Common: Replace enable_if with concepts and other minor modernizations.
Diffstat (limited to 'Source/Core/Common')
| -rw-r--r-- | Source/Core/Common/BitField.h | 18 | ||||
| -rw-r--r-- | Source/Core/Common/BitUtils.h | 10 | ||||
| -rw-r--r-- | Source/Core/Common/ChunkFile.h | 7 | ||||
| -rw-r--r-- | Source/Core/Common/Config/ConfigInfo.h | 15 | ||||
| -rw-r--r-- | Source/Core/Common/Config/Layer.h | 5 | ||||
| -rw-r--r-- | Source/Core/Common/EnumFormatter.h | 3 | ||||
| -rw-r--r-- | Source/Core/Common/EnumMap.h | 9 | ||||
| -rw-r--r-- | Source/Core/Common/SFMLHelper.h | 11 | ||||
| -rw-r--r-- | Source/Core/Common/TypeUtils.h | 4 |
9 files changed, 32 insertions, 50 deletions
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 <std::size_t position, std::size_t bits, typename T, - // StorageType is T for non-enum types and the underlying type of T if - // T is an enumeration. Note that T is wrapped within an enable_if in the - // former case to workaround compile errors which arise when using - // std::underlying_type<T>::type directly. - typename StorageType = typename std::conditional_t< - std::is_enum<T>::value, std::underlying_type<T>, std::enable_if<true, T>>::type> + // StorageType is T for non-enum or the underlying-type for an enum. + typename StorageType = std::conditional_t<std::is_enum_v<T>, std::underlying_type<T>, + std::type_identity<T>>::type> struct BitField { private: @@ -212,12 +209,9 @@ class BitFieldArrayIterator; #pragma pack(1) template <std::size_t position, std::size_t bits, std::size_t size, typename T, - // StorageType is T for non-enum types and the underlying type of T if - // T is an enumeration. Note that T is wrapped within an enable_if in the - // former case to workaround compile errors which arise when using - // std::underlying_type<T>::type directly. - typename StorageType = typename std::conditional_t< - std::is_enum<T>::value, std::underlying_type<T>, std::enable_if<true, T>>::type> + // StorageType is T for non-enum or the underlying-type for an enum. + typename StorageType = std::conditional_t<std::is_enum_v<T>, std::underlying_type<T>, + std::type_identity<T>>::type> struct BitFieldArray { using Ref = BitFieldArrayRef<position, bits, size, T, StorageType>; 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 <bit> #include <climits> #include <cstddef> -#include <cstdint> #include <cstring> #include <initializer_list> #include <type_traits> @@ -117,8 +116,8 @@ constexpr Result ExtractBits(const T src) noexcept template <typename T> constexpr bool IsValidLowMask(const T mask) noexcept { - static_assert(std::is_integral<T>::value, "Mask must be an integral type."); - static_assert(std::is_unsigned<T>::value, "Signed masks can introduce hard to find bugs."); + static_assert(std::is_integral_v<T>, "Mask must be an integral type."); + static_assert(std::is_unsigned_v<T>, "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 <typename S> - inline typename std::enable_if<std::is_same<S, T>() && !std::is_const<PtrType>()>::type - operator=(const S& source) + auto& operator=(const T& source) requires(!std::is_const_v<PtrType>) { 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<u32>(x.size())); } - template <typename T, typename std::enable_if_t<std::is_trivially_copyable_v<T>, int> = 0> + template <typename T> + requires(std::is_trivially_copyable_v<T>) void DoArray(T* x, u32 count) { DoVoid(x, count * sizeof(T)); } - template <typename T, typename std::enable_if_t<!std::is_trivially_copyable_v<T>, int> = 0> + template <typename T> + requires(!std::is_trivially_copyable_v<T>) 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 <mutex> #include <shared_mutex> #include <string> -#include <type_traits> #include <utility> #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 <typename T> -using UnderlyingType = typename std::enable_if_t<std::is_enum<T>{}, std::underlying_type<T>>::type; -} // namespace detail - struct Location { System system{}; @@ -54,8 +47,7 @@ public: // Make it easy to convert Info<Enum> into Info<UnderlyingType<Enum>> // so that enum settings can still easily work with code that doesn't care about the enum values. - template <typename Enum, - std::enable_if_t<std::is_same<T, detail::UnderlyingType<Enum>>::value>* = nullptr> + template <Common::TypedEnum<T> Enum> Info(const Info<Enum>& other) { *this = other; @@ -80,8 +72,7 @@ public: // Make it easy to convert Info<Enum> into Info<UnderlyingType<Enum>> // so that enum settings can still easily work with code that doesn't care about the enum values. - template <typename Enum, - std::enable_if_t<std::is_same<T, detail::UnderlyingType<Enum>>::value>* = nullptr> + template <Common::TypedEnum<T> Enum> Info<T>& operator=(const Info<Enum>& 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 <typename T, std::enable_if_t<!std::is_enum<T>::value>* = nullptr> +template <typename T> +requires(!Common::Enum<T>) std::optional<T> TryParse(const std::string& str_value) { T value; @@ -32,7 +33,7 @@ std::optional<T> TryParse(const std::string& str_value) return value; } -template <typename T, std::enable_if_t<std::is_enum<T>::value>* = nullptr> +template <Common::Enum T> std::optional<T> TryParse(const std::string& str_value) { const auto result = TryParse<std::underlying_type_t<T>>(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 <auto last_member> +template <Common::Enum auto last_member> class EnumFormatter { using T = decltype(last_member); - static_assert(std::is_enum_v<T>); 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 <array> -#include <type_traits> #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 <typename V, auto last_member> +template <typename V, Common::Enum auto last_member> class EnumMap final { using T = decltype(last_member); - static_assert(std::is_enum_v<T>); static constexpr size_t s_size = static_cast<size_t>(last_member) + 1; using array_type = std::array<V, s_size>; @@ -34,8 +32,9 @@ public: constexpr EnumMap& operator=(EnumMap&& other) = default; // Constructor that accepts exactly size Vs (enforcing that all must be specified). - template <typename... T, typename = std::enable_if_t<Common::IsNOf<V, s_size, T...>::value>> - constexpr EnumMap(T... values) : m_array{static_cast<V>(values)...} + template <typename... T> + constexpr EnumMap(T... values) requires(Common::IsNOf<V, s_size, T...>::value) + : m_array{static_cast<V>(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 <type_traits> - #include <SFML/Network/Packet.hpp> #include "Common/CommonTypes.h" +#include "Common/EnumUtils.h" #include "Common/Swap.h" +#include "Common/TypeUtils.h" sf::Packet& operator>>(sf::Packet& packet, Common::BigEndianValue<u16>& data); sf::Packet& operator>>(sf::Packet& packet, Common::BigEndianValue<u32>& data); sf::Packet& operator>>(sf::Packet& packet, Common::BigEndianValue<u64>& data); -template <typename Enum, std::enable_if_t<std::is_enum_v<Enum>>* = nullptr> +template <Common::Enum Enum> sf::Packet& operator<<(sf::Packet& packet, Enum e) { - using Underlying = std::underlying_type_t<Enum>; - packet << static_cast<Underlying>(e); + packet << Common::ToUnderlying(e); return packet; } -template <typename Enum, std::enable_if_t<std::is_enum_v<Enum>>* = nullptr> +template <Common::Enum Enum> sf::Packet& operator>>(sf::Packet& packet, Enum& e) { using Underlying = std::underlying_type_t<Enum>; 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<ObjectType<&Bar::c>, Bar>); // Template for checking if Types is count occurrences of T. template <typename T, size_t count, typename... Ts> -struct IsNOf : std::integral_constant<bool, std::conjunction_v<std::is_convertible<Ts, T>...> && - sizeof...(Ts) == count> +struct IsNOf : std::bool_constant<std::conjunction_v<std::is_convertible<Ts, T>...> && + sizeof...(Ts) == count> { }; |
