diff --git a/Utilities/BitField.h b/Utilities/BitField.h index 32785e5e7e..b2243dbe1e 100644 --- a/Utilities/BitField.h +++ b/Utilities/BitField.h @@ -256,7 +256,7 @@ struct ff_t : bf_base #endif template -struct fmt_unveil, void> +struct fmt_unveil> { using type = typename fmt_unveil>::type; @@ -267,7 +267,7 @@ struct fmt_unveil, void> }; template -struct fmt_unveil, void> +struct fmt_unveil> { using type = typename fmt_unveil>::type; @@ -278,7 +278,7 @@ struct fmt_unveil, void> }; template -struct fmt_unveil, void> +struct fmt_unveil> { using type = typename fmt_unveil>::type; diff --git a/Utilities/StrFmt.h b/Utilities/StrFmt.h index f83cbe49fe..0f1d0fb604 100644 --- a/Utilities/StrFmt.h +++ b/Utilities/StrFmt.h @@ -22,7 +22,7 @@ namespace fmt #endif } -template +template struct fmt_unveil { static_assert(sizeof(T) > 0, "fmt_unveil<> error: incomplete type"); @@ -54,7 +54,8 @@ struct fmt_unveil }; template -struct fmt_unveil && sizeof(T) <= 8 && alignof(T) <= 8>> + requires(std::is_integral_v && sizeof(T) <= 8 && alignof(T) <= 8) +struct fmt_unveil { using type = T; @@ -65,7 +66,8 @@ struct fmt_unveil && sizeof(T) <= 8 && }; template -struct fmt_unveil && sizeof(T) <= 8 && alignof(T) <= 8>> + requires(std::is_floating_point_v && sizeof(T) <= 8 && alignof(T) <= 8) +struct fmt_unveil { using type = T; @@ -77,7 +79,8 @@ struct fmt_unveil && sizeof(T) < }; template -struct fmt_unveil>> + requires std::is_enum_v +struct fmt_unveil { using type = T; @@ -88,7 +91,7 @@ struct fmt_unveil>> }; template -struct fmt_unveil +struct fmt_unveil { using type = std::add_const_t*; @@ -105,7 +108,7 @@ namespace fmt } template -struct fmt_unveil +struct fmt_unveil { using type = std::add_const_t*; @@ -116,7 +119,7 @@ struct fmt_unveil }; template -struct fmt_unveil, void> +struct fmt_unveil> { using type = typename fmt_unveil::type; @@ -200,13 +203,13 @@ struct fmt_class_string }; template <> -struct fmt_class_string +struct fmt_class_string { static void format(std::string& out, u64 arg); }; template -struct fmt_class_string : fmt_class_string +struct fmt_class_string : fmt_class_string { // Classify all pointers as const void* }; @@ -218,18 +221,18 @@ struct fmt_class_string }; template <> -struct fmt_class_string : fmt_class_string +struct fmt_class_string : fmt_class_string { // Classify char* as const char* }; template <> -struct fmt_class_string : fmt_class_string +struct fmt_class_string : fmt_class_string { }; template <> -struct fmt_class_string : fmt_class_string +struct fmt_class_string : fmt_class_string { }; @@ -240,7 +243,7 @@ struct fmt_class_string }; template <> -struct fmt_class_string : fmt_class_string +struct fmt_class_string : fmt_class_string { }; diff --git a/Utilities/bit_set.h b/Utilities/bit_set.h index f418fde13e..8b98ae0fd4 100644 --- a/Utilities/bit_set.h +++ b/Utilities/bit_set.h @@ -385,7 +385,7 @@ public: }; template -struct fmt_unveil, void> +struct fmt_unveil> { // Format as is using type = bs_t; diff --git a/rpcs3/Emu/CPU/CPUDisAsm.h b/rpcs3/Emu/CPU/CPUDisAsm.h index 1b4fc5515b..9e9054d62b 100644 --- a/rpcs3/Emu/CPU/CPUDisAsm.h +++ b/rpcs3/Emu/CPU/CPUDisAsm.h @@ -110,7 +110,8 @@ protected: virtual u32 DisAsmBranchTarget(s32 /*imm*/); // TODO: Add builtin fmt helpper for best performance - template , int> = 0> + template + requires std::is_integral_v static std::string SignedHex(T value) { const auto v = static_cast>(value); diff --git a/rpcs3/Emu/CPU/CPUTranslator.h b/rpcs3/Emu/CPU/CPUTranslator.h index 7bab6b335a..088bd0801b 100644 --- a/rpcs3/Emu/CPU/CPUTranslator.h +++ b/rpcs3/Emu/CPU/CPUTranslator.h @@ -2,6 +2,12 @@ #ifdef LLVM_AVAILABLE +#include "util/types.hpp" +#include "util/sysinfo.hpp" +#include "Utilities/StrFmt.h" +#include "Utilities/JIT.h" +#include "util/v128.hpp" + #ifdef _MSC_VER #pragma warning(push, 0) #else @@ -24,7 +30,9 @@ #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/IntrinsicsX86.h" +#ifdef ARCH_ARM64 #include "llvm/IR/IntrinsicsAArch64.h" +#endif #include "llvm/IR/InlineAsm.h" #ifdef _MSC_VER @@ -33,12 +41,6 @@ #pragma GCC diagnostic pop #endif -#include "util/types.hpp" -#include "util/sysinfo.hpp" -#include "Utilities/StrFmt.h" -#include "Utilities/JIT.h" - -#include "util/v128.hpp" #include #include @@ -60,9 +62,8 @@ template concept LLVMValue = (std::is_pointer_v) && (std::is_base_of_v>); template -concept DSLValue = requires (T& v) -{ - { v.eval(std::declval*>()) } -> LLVMValue; +concept DSLValue = requires(T& v, llvm::IRBuilder<>* ir) { + { v.eval(ir) } -> LLVMValue; }; template @@ -476,31 +477,33 @@ struct llvm_value_t : llvm_value_t > template using llvm_expr_t = std::decay_t; -template +template struct is_llvm_expr { }; -template -struct is_llvm_expr().eval(std::declval*>()))>> +template +struct is_llvm_expr { using type = typename std::decay_t::type; }; -template +template struct is_llvm_expr_of { static constexpr bool ok = false; }; template -struct is_llvm_expr_of::type, typename is_llvm_expr::type>> + requires(requires { typename is_llvm_expr::type; } && requires { typename is_llvm_expr::type; }) +struct is_llvm_expr_of { static constexpr bool ok = std::is_same_v::type, typename is_llvm_expr::type>; }; template -using llvm_common_t = std::enable_if_t<(is_llvm_expr_of::ok && ...), typename is_llvm_expr::type>; + requires(is_llvm_expr_of::ok && ...) +using llvm_common_t = typename is_llvm_expr::type; template using llvm_match_tuple = decltype(std::tuple_cat(std::declval&>().match(std::declval(), nullptr)...)); @@ -1606,7 +1609,8 @@ struct llvm_ord }; template -llvm_ord(T&&) -> llvm_ord>::value, T&&>>; + requires is_llvm_cmp>::value +llvm_ord(T&&) -> llvm_ord; template > struct llvm_uno @@ -1659,7 +1663,8 @@ struct llvm_uno }; template -llvm_uno(T&&) -> llvm_uno>::value, T&&>>; + requires is_llvm_cmp>::value +llvm_uno(T&&) -> llvm_uno; template inline llvm_cmp operator ==(T1&& a1, T2&& a2) @@ -3020,7 +3025,7 @@ struct llvm_calli if (((std::get(r) = std::get(a).match(v[I], _m), v[I]) && ...)) { return std::tuple_cat(std::get(r)...); - } + } } } } @@ -3194,14 +3199,16 @@ public: return {}; } - template > + template + requires requires { typename llvm_common_t; } static auto match_expr(llvm::Value* v, llvm::Module* _m, T&& expr) { auto r = expr.match(v, _m); return std::tuple_cat(std::make_tuple(v != nullptr), r); } - template > + template + requires requires { typename llvm_common_t; } auto match_expr(T&& arg, U&& expr) -> decltype(std::tuple_cat(std::make_tuple(false), expr.match(std::declval(), nullptr))) { auto v = arg.eval(m_ir); @@ -3236,202 +3243,235 @@ public: return expr_t{std::forward(expr), std::move(matcher)}; } - template >::value>> + template + requires is_llvm_cmp>::value static auto fcmp_ord(T&& cmp_expr) { return llvm_ord{std::forward(cmp_expr)}; } - template >::value>> + template + requires is_llvm_cmp>::value static auto fcmp_uno(T&& cmp_expr) { return llvm_uno{std::forward(cmp_expr)}; } - template ::is_ok>> + template + requires llvm_noncast::is_ok static auto noncast(T&& expr) { return llvm_noncast{std::forward(expr)}; } - template ::is_ok>> + template + requires llvm_bitcast::is_ok static auto bitcast(T&& expr) { return llvm_bitcast{std::forward(expr)}; } - template ::is_ok>> + template + requires llvm_fpcast::is_ok static auto fpcast(T&& expr) { return llvm_fpcast{std::forward(expr)}; } - template ::is_ok>> + template + requires llvm_trunc::is_ok static auto trunc(T&& expr) { return llvm_trunc{std::forward(expr)}; } - template ::is_ok>> + template + requires llvm_sext::is_ok static auto sext(T&& expr) { return llvm_sext{std::forward(expr)}; } - template ::is_ok>> + template + requires llvm_zext::is_ok static auto zext(T&& expr) { return llvm_zext{std::forward(expr)}; } - template ::is_ok>> + template + requires llvm_select::is_ok static auto select(T&& c, U&& a, V&& b) { return llvm_select{std::forward(c), std::forward(a), std::forward(b)}; } - template ::is_ok>> + template + requires llvm_min::is_ok static auto min(T&& a, U&& b) { return llvm_min{std::forward(a), std::forward(b)}; } - template ::is_ok>> + template + requires llvm_min::is_ok static auto max(T&& a, U&& b) { return llvm_max{std::forward(a), std::forward(b)}; } - template ::is_ok>> + template + requires llvm_fshl::is_ok static auto fshl(T&& a, U&& b, V&& c) { return llvm_fshl{std::forward(a), std::forward(b), std::forward(c)}; } - template ::is_ok>> + template + requires llvm_fshr::is_ok static auto fshr(T&& a, U&& b, V&& c) { return llvm_fshr{std::forward(a), std::forward(b), std::forward(c)}; } - template ::is_ok>> + template + requires llvm_rol::is_ok static auto rol(T&& a, U&& b) { return llvm_rol{std::forward(a), std::forward(b)}; } - template ::is_ok>> + template + requires llvm_add_sat::is_ok static auto add_sat(T&& a, U&& b) { return llvm_add_sat{std::forward(a), std::forward(b)}; } - template ::is_ok>> + template + requires llvm_sub_sat::is_ok static auto sub_sat(T&& a, U&& b) { return llvm_sub_sat{std::forward(a), std::forward(b)}; } - template ::is_ok>> + template + requires llvm_extract::is_ok static auto extract(T&& v, U&& i) { return llvm_extract{std::forward(v), std::forward(i)}; } - template >::is_ok>> + template + requires llvm_extract>::is_ok static auto extract(T&& v, u32 i) { return llvm_extract>{std::forward(v), llvm_const_int{i}}; } - template ::is_ok>> + template + requires llvm_insert::is_ok static auto insert(T&& v, U&& i, V&& e) { return llvm_insert{std::forward(v), std::forward(i), std::forward(e)}; } - template , V>::is_ok>> + template + requires llvm_insert, V>::is_ok static auto insert(T&& v, u32 i, V&& e) { return llvm_insert, V>{std::forward(v), llvm_const_int{i}, std::forward(e)}; } - template ::is_ok>> + template + requires llvm_const_int::is_ok static auto splat(u64 c) { return llvm_const_int{c}; } - template ::is_ok>> + template + requires llvm_const_float::is_ok static auto fsplat(f64 c) { return llvm_const_float{c}; } - template ::is_ok>> + template + requires llvm_splat::is_ok static auto vsplat(U&& v) { return llvm_splat{std::forward(v)}; } - template ::is_ok>> + template + requires llvm_const_vector::is_ok static auto build(Args... args) { return llvm_const_vector{static_cast>(args)...}; } - template ::is_ok>> + template + requires llvm_zshuffle::is_ok static auto zshuffle(T&& v, Args... indices) { return llvm_zshuffle{std::forward(v), {static_cast(indices)...}}; } - template ::is_ok>> + template + requires llvm_shuffle2::is_ok static auto shuffle2(T&& v1, U&& v2, Args... indices) { return llvm_shuffle2{std::forward(v1), std::forward(v2), {static_cast(indices)...}}; } - template ::is_ok>> + template + requires llvm_ctlz::is_ok static auto ctlz(T&& a) { return llvm_ctlz{std::forward(a)}; } - template ::is_ok>> + template + requires llvm_ctpop::is_ok static auto ctpop(T&& a) { return llvm_ctpop{std::forward(a)}; } // Average: (a + b + 1) >> 1 - template ::is_ok>> + template + requires llvm_avg::is_ok static auto avg(T&& a, U&& b) { return llvm_avg{std::forward(a), std::forward(b)}; } - template ::is_ok>> + template + requires llvm_fsqrt::is_ok static auto fsqrt(T&& a) { return llvm_fsqrt{std::forward(a)}; } - template ::is_ok>> + template + requires llvm_fabs::is_ok static auto fabs(T&& a) { return llvm_fabs{std::forward(a)}; } // Optionally opportunistic hardware FMA, can be used if results are identical for all possible input values - template ::is_ok>> + template + requires llvm_fmuladd::is_ok static auto fmuladd(T&& a, U&& b, V&& c, bool strict_fma) { return llvm_fmuladd{std::forward(a), std::forward(b), std::forward(c), strict_fma}; } // Opportunistic hardware FMA, can be used if results are identical for all possible input values - template ::is_ok>> + template + requires llvm_fmuladd::is_ok auto fmuladd(T&& a, U&& b, V&& c) { return llvm_fmuladd{std::forward(a), std::forward(b), std::forward(c), m_use_fma}; @@ -3754,7 +3794,8 @@ public: return load_const(g, i, get_type()); } - template requires requires () { std::declval().eval(std::declval*>()); } + template + requires requires(I& i, llvm::IRBuilder<>* ir) { i.eval(ir); } value_t load_const(llvm::GlobalVariable* g, I i) { value_t result; @@ -3873,7 +3914,8 @@ public: return llvm_calli{"any_select_by_bit4", {std::forward(m), std::forward(a), std::forward(b)}}; } - template , f32[4]>>> + template + requires std::is_same_v, f32[4]> static auto fre(T&& a) { #if defined(ARCH_X64) @@ -3883,7 +3925,8 @@ public: #endif } - template , f32[4]>>> + template + requires std::is_same_v, f32[4]> static auto frsqe(T&& a) { #if defined(ARCH_X64) @@ -3893,7 +3936,8 @@ public: #endif } - template , f32[4]>>> + template + requires std::is_same_v, f32[4]> static auto fmax(T&& a, U&& b) { #if defined(ARCH_X64) @@ -3903,7 +3947,8 @@ public: #endif } - template , f32[4]>>> + template + requires std::is_same_v, f32[4]> static auto fmin(T&& a, U&& b) { #if defined(ARCH_X64) @@ -3913,13 +3958,15 @@ public: #endif } - template , u8[16]>>> + template + requires std::is_same_v, u8[16]> static auto vdbpsadbw(T&& a, U&& b, u8 c) { return llvm_calli>{"llvm.x86.avx512.dbpsadbw.128", {std::forward(a), std::forward(b), llvm_const_int{c}}}; } - template , f32[4]>>> + template + requires std::is_same_v, f32[4]> static auto vrangeps(T&& a, U&& b, u8 c, u8 d) { return llvm_calli, T, llvm_const_int>{"llvm.x86.avx512.mask.range.ps.128", {std::forward(a), std::forward(b), llvm_const_int{c}, std::forward(a), llvm_const_int{d}}}; @@ -3928,7 +3975,7 @@ public: // Format llvm::SizeType template <> -struct fmt_unveil +struct fmt_unveil { using type = usz; diff --git a/rpcs3/Emu/Cell/ErrorCodes.h b/rpcs3/Emu/Cell/ErrorCodes.h index 7b3b0dc1bb..7f6a3892da 100644 --- a/rpcs3/Emu/Cell/ErrorCodes.h +++ b/rpcs3/Emu/Cell/ErrorCodes.h @@ -82,11 +82,11 @@ constexpr FORCE_INLINE CellNotAnError not_an_error(const T& value) return static_cast(static_cast(value)); } -template +template struct ppu_gpr_cast_impl; template <> -struct ppu_gpr_cast_impl +struct ppu_gpr_cast_impl { static inline u64 to(const error_code& code) { diff --git a/rpcs3/Emu/Cell/Modules/cellSail.h b/rpcs3/Emu/Cell/Modules/cellSail.h index 2b34e015b4..c8b9716ada 100644 --- a/rpcs3/Emu/Cell/Modules/cellSail.h +++ b/rpcs3/Emu/Cell/Modules/cellSail.h @@ -672,11 +672,11 @@ union CellSailEvent be_t value; }; -template +template struct ppu_gpr_cast_impl; -template<> -struct ppu_gpr_cast_impl +template <> +struct ppu_gpr_cast_impl { static inline u64 to(const CellSailEvent& event) { diff --git a/rpcs3/Emu/Cell/Modules/sceNpTrophy.h b/rpcs3/Emu/Cell/Modules/sceNpTrophy.h index dfea517fe0..941727648d 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpTrophy.h +++ b/rpcs3/Emu/Cell/Modules/sceNpTrophy.h @@ -3,6 +3,7 @@ #include "util/types.hpp" #include "Emu/Memory/vm_ptr.h" #include "Emu/Cell/ErrorCodes.h" +#include #include #include diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 9f94ad50f6..0e4ec1bb1a 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -382,14 +382,15 @@ public: static_assert(ppu_join_status::max <= ppu_join_status{ppu_thread::id_base}); -template +template struct ppu_gpr_cast_impl { static_assert(!sizeof(T), "Invalid type for ppu_gpr_cast<>"); }; -template -struct ppu_gpr_cast_impl || std::is_enum_v>> +template + requires std::is_integral_v || std::is_enum_v +struct ppu_gpr_cast_impl { static_assert(sizeof(T) <= 8, "Too big integral type for ppu_gpr_cast<>()"); static_assert(std::is_same_v, bool> == false, "bool type is deprecated in ppu_gpr_cast<>(), use b8 instead"); @@ -405,8 +406,8 @@ struct ppu_gpr_cast_impl || std::is_en } }; -template<> -struct ppu_gpr_cast_impl +template <> +struct ppu_gpr_cast_impl { static inline u64 to(const b8& value) { @@ -419,8 +420,8 @@ struct ppu_gpr_cast_impl } }; -template -struct ppu_gpr_cast_impl, void> +template +struct ppu_gpr_cast_impl> { static inline u64 to(const vm::_ptr_base& value) { @@ -433,8 +434,8 @@ struct ppu_gpr_cast_impl, void> } }; -template -struct ppu_gpr_cast_impl, void> +template +struct ppu_gpr_cast_impl> { static inline u64 to(const vm::_ref_base& value) { @@ -448,7 +449,7 @@ struct ppu_gpr_cast_impl, void> }; template <> -struct ppu_gpr_cast_impl +struct ppu_gpr_cast_impl { static inline u64 to(const vm::null_t& /*value*/) { diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index 3884e439b2..b3c898c23b 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -26,7 +26,7 @@ template concept IdmBaseCompatible = (std::is_final_v ? IdmCompatible : !!(requires () { u32{T::id_step}, u32{T::id_count}; })); template -concept IdmSavable = IdmBaseCompatible && T::savestate_init_pos != 0 && (requires () { std::declval().save(std::declval>()); }); +concept IdmSavable = IdmBaseCompatible && T::savestate_init_pos != 0 && (requires(T& t, utils::serial& ar) { t.save(stx::exact_t(ar)); }); // If id_base is declared in base type, than storage type must declare id_type template @@ -105,7 +105,7 @@ namespace id_manager } // ID traits - template + template struct id_traits_load_func { static constexpr pointer_keeper(*load)(utils::serial&) = [](utils::serial& ar) -> pointer_keeper @@ -126,7 +126,8 @@ namespace id_manager }; template - struct id_traits_load_func> + requires requires() { &T::load; } + struct id_traits_load_func { static constexpr pointer_keeper(*load)(utils::serial&) = [](utils::serial& ar) -> pointer_keeper { @@ -134,14 +135,15 @@ namespace id_manager }; }; - template + template struct id_traits_savable_func { static constexpr bool(*savable)(void*) = [](void*) -> bool { return true; }; }; template - struct id_traits_savable_func> + requires requires { &T::savable; } + struct id_traits_savable_func { static constexpr bool(*savable)(void* ptr) = [](void* ptr) -> bool { return static_cast(ptr)->savable(); }; }; diff --git a/rpcs3/Emu/Memory/vm_ptr.h b/rpcs3/Emu/Memory/vm_ptr.h index eb70ee8f13..28accf7316 100644 --- a/rpcs3/Emu/Memory/vm_ptr.h +++ b/rpcs3/Emu/Memory/vm_ptr.h @@ -342,21 +342,24 @@ namespace vm template using bcpptr = bpptr; // Perform static_cast (for example, vm::ptr to vm::ptr) - template*>(std::declval()))> + template + requires requires(T* t) { static_cast*>(t); } inline _ptr_base, u32> static_ptr_cast(const _ptr_base& other) { return vm::cast(other.addr()); } // Perform const_cast (for example, vm::cptr to vm::ptr) - template*>(std::declval()))> + template + requires requires(T* t) { const_cast*>(t); } inline _ptr_base, u32> const_ptr_cast(const _ptr_base& other) { return vm::cast(other.addr()); } // Perform reinterpret cast - template *>(std::declval()))> + template + requires requires(T* t) { reinterpret_cast*>(t); } inline _ptr_base, u32> unsafe_ptr_cast(const _ptr_base& other) { return vm::cast(other.addr()); @@ -426,8 +429,8 @@ struct to_se, Se> }; // Format pointer -template -struct fmt_unveil, void> +template +struct fmt_unveil> { using type = vm::_ptr_base; // Use only T, ignoring AT diff --git a/rpcs3/Emu/Memory/vm_ref.h b/rpcs3/Emu/Memory/vm_ref.h index 5abded43b0..59e6daa8f0 100644 --- a/rpcs3/Emu/Memory/vm_ref.h +++ b/rpcs3/Emu/Memory/vm_ref.h @@ -193,8 +193,8 @@ struct to_se, Se> }; // Forbid formatting -template -struct fmt_unveil, void> +template +struct fmt_unveil> { static_assert(!sizeof(T), "vm::_ref_base<>: ambiguous format argument"); }; diff --git a/rpcs3/Emu/RSX/Common/expected.hpp b/rpcs3/Emu/RSX/Common/expected.hpp index 39254c3f34..d3da0a402d 100644 --- a/rpcs3/Emu/RSX/Common/expected.hpp +++ b/rpcs3/Emu/RSX/Common/expected.hpp @@ -94,11 +94,11 @@ namespace rsx return value; } - template>> - operator bool() const - { - return error.empty(); - } + operator bool() const + requires(!std::is_same_v) + { + return error.empty(); + } operator std::pair() const { diff --git a/rpcs3/util/asm.hpp b/rpcs3/util/asm.hpp index bab63ccfc6..947aa4f54a 100644 --- a/rpcs3/util/asm.hpp +++ b/rpcs3/util/asm.hpp @@ -376,21 +376,24 @@ namespace utils } // Align to power of 2 - template >> + template + requires std::is_unsigned_v constexpr std::make_unsigned_t> align(T value, U align) { return static_cast>>((value + (align - 1)) & (T{0} - align)); } // General purpose aligned division, the result is rounded up not truncated - template >> + template + requires std::is_unsigned_v constexpr T aligned_div(T value, std::type_identity_t align) { return static_cast(value / align + T{!!(value % align)}); } // General purpose aligned division, the result is rounded to nearest - template >> + template + requires std::is_integral_v constexpr T rounded_div(T value, std::type_identity_t align) { if constexpr (std::is_unsigned_v) diff --git a/rpcs3/util/atomic.hpp b/rpcs3/util/atomic.hpp index 4c3ab8959c..593b7a51f1 100644 --- a/rpcs3/util/atomic.hpp +++ b/rpcs3/util/atomic.hpp @@ -173,7 +173,8 @@ namespace atomic_wait constexpr list& operator=(const list&) noexcept = default; - template ().wait(any_value))...>> + template + requires(requires(U& u) { u.wait(any_value); } && ...) constexpr list(U&... vars) : m_info{{&vars, 0}...} { @@ -190,7 +191,8 @@ namespace atomic_wait return *this; } - template ().wait(any_value))>> + template + requires(requires(T2& t2) { t2.wait(any_value); }) constexpr void set(T2& var, U value) { static_assert(Index < Max); @@ -229,7 +231,8 @@ namespace atomic_wait } }; - template ().wait(any_value))...>> + template + requires(requires(T& t) { t.wait(any_value); } && ...) list(T&... vars) -> list; } diff --git a/rpcs3/util/endian.hpp b/rpcs3/util/endian.hpp index c4748b34d5..169eeffbad 100644 --- a/rpcs3/util/endian.hpp +++ b/rpcs3/util/endian.hpp @@ -267,8 +267,9 @@ private: } } -public: - template ())> + public: + template + requires requires(const T2& t2) { +t2; } constexpr bool operator==(const T2& rhs) const noexcept { using R = std::common_type_t; diff --git a/rpcs3/util/fixed_typemap.hpp b/rpcs3/util/fixed_typemap.hpp index 85d04c57a1..2e95a06689 100644 --- a/rpcs3/util/fixed_typemap.hpp +++ b/rpcs3/util/fixed_typemap.hpp @@ -143,7 +143,8 @@ namespace stx *std::launder(static_cast(ptr)) = state; } - template requires requires (T& a) { a.save(std::declval>()); } + template + requires requires(T& a, utils::serial& ar) { a.save(ar); } static void call_save(void* ptr, utils::serial& ar) noexcept { std::launder(static_cast(ptr))->save(stx::exact_t(ar)); @@ -169,7 +170,7 @@ namespace stx r.thread_op = &call_thread_op; } - if constexpr (!!(requires (T& a) { a.save(std::declval>()); })) + if constexpr (!!(requires(T& a, utils::serial& ar) { a.save(ar); })) { r.save = &call_save; } diff --git a/rpcs3/util/fnv_hash.hpp b/rpcs3/util/fnv_hash.hpp index dea3d8b480..1da02d02a5 100644 --- a/rpcs3/util/fnv_hash.hpp +++ b/rpcs3/util/fnv_hash.hpp @@ -14,7 +14,8 @@ namespace rpcs3 return static_cast(value); } - template >> + template + requires std::is_integral_v static inline usz hash64(usz hash_value, T data) { hash_value ^= data; diff --git a/rpcs3/util/serialization.hpp b/rpcs3/util/serialization.hpp index 5e139e05f8..730c81c24c 100644 --- a/rpcs3/util/serialization.hpp +++ b/rpcs3/util/serialization.hpp @@ -18,9 +18,8 @@ namespace utils }; template - concept Bitcopy = (std::is_arithmetic_v) || (std::is_enum_v) || Integral || requires () - { - std::enable_if_t>(); + concept Bitcopy = (std::is_arithmetic_v) || (std::is_enum_v) || Integral || requires() { + typename T::enable_bitcopy; }; template @@ -30,7 +29,7 @@ namespace utils }; template - concept ListAlike = requires (std::remove_cvref_t& obj) { obj.insert(obj.end(), std::declval()); }; + concept ListAlike = requires(std::remove_cvref_t& obj, T::value_type item) { obj.insert(obj.end(), item); }; struct serial; @@ -427,7 +426,8 @@ public: return true; } - template requires requires (T& obj) { (obj.*(&T::operator()))(std::declval>()); } + template + requires requires(T& obj, utils::serial& ar) { (obj.*(&T::operator()))(ar); } bool serialize(T& obj) { obj(*this); diff --git a/rpcs3/util/to_endian.hpp b/rpcs3/util/to_endian.hpp index 6bd101ace0..f4ec045d91 100644 --- a/rpcs3/util/to_endian.hpp +++ b/rpcs3/util/to_endian.hpp @@ -6,17 +6,18 @@ union v128; // Type converter: converts native endianness arithmetic/enum types to appropriate se_t<> type -template +template struct to_se { - template + template struct to_se_ { using type = T2; }; template - struct to_se_ || std::is_enum_v>> + requires std::is_arithmetic_v || std::is_enum_v + struct to_se_ { using type = std::conditional_t<(sizeof(T2) > 1), se_t, T2>; }; @@ -44,14 +45,16 @@ struct to_se }; template -struct to_se>> + requires(!std::is_array_v) +struct to_se { // Move const qualifier using type = const typename to_se::type; }; template -struct to_se && !std::is_const_v>> + requires(!std::is_array_v && !std::is_const_v) +struct to_se { // Move volatile qualifier using type = volatile typename to_se::type; diff --git a/rpcs3/util/types.hpp b/rpcs3/util/types.hpp index f01e558e92..0bbf45074c 100644 --- a/rpcs3/util/types.hpp +++ b/rpcs3/util/types.hpp @@ -272,14 +272,16 @@ struct alignas(16) u128 u128() noexcept = default; - template , u64> = 0> + template + requires std::is_unsigned_v constexpr u128(T arg) noexcept : lo(arg) , hi(0) { } - template , s64> = 0> + template + requires std::is_signed_v constexpr u128(T arg) noexcept : lo(s64{arg}) , hi(s64{arg} >> 63)