summaryrefslogtreecommitdiff
path: root/Source/Core/Common
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2025-05-05 19:30:53 -0500
committerJordan Woyak <jordan.woyak@gmail.com>2025-05-05 19:34:24 -0500
commit2dc975fa923cfabcd0ee4459eb608219a72e4e02 (patch)
treeb11251616ef7581e5f5efdebf8587fff84f96e1d /Source/Core/Common
parent210b5cbf66a8c1aa28cf95aff8985ea54138ef8b (diff)
Common: Replace enable_if with concepts and other minor modernizations.
Diffstat (limited to 'Source/Core/Common')
-rw-r--r--Source/Core/Common/BitField.h18
-rw-r--r--Source/Core/Common/BitUtils.h10
-rw-r--r--Source/Core/Common/ChunkFile.h7
-rw-r--r--Source/Core/Common/Config/ConfigInfo.h15
-rw-r--r--Source/Core/Common/Config/Layer.h5
-rw-r--r--Source/Core/Common/EnumFormatter.h3
-rw-r--r--Source/Core/Common/EnumMap.h9
-rw-r--r--Source/Core/Common/SFMLHelper.h11
-rw-r--r--Source/Core/Common/TypeUtils.h4
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>
{
};