diff --git a/rpcs3/util/shared_ptr.hpp b/rpcs3/util/shared_ptr.hpp index 6d5c975b10..a3b339845d 100644 --- a/rpcs3/util/shared_ptr.hpp +++ b/rpcs3/util/shared_ptr.hpp @@ -6,55 +6,58 @@ namespace stx { -#ifndef _MSC_VER -#pragma GCC diagnostic push -#ifdef __clang__ -#pragma GCC diagnostic ignored "-Wundefined-var-template" -#pragma GCC diagnostic ignored "-Wundefined-internal" -#endif -#endif + namespace detail + { + template + union fake_t + { + char dummy; + T data; - // Not defined anywhere (and produces a useless warning) - template - extern X sample; + fake_t() noexcept {} + ~fake_t() {} + }; + + template + static const fake_t> sample{}; + } + + template + constexpr bool is_same_ptr_test(const volatile Y*, ...) + { + // Can't sample abstract class + return false; + } + + template , int> = 0> + constexpr bool is_same_ptr_test(const volatile Y* ptr = std::addressof(detail::sample.data)) + { + return static_cast(ptr) == static_cast(ptr); + } // Checks whether the cast between two types is the same pointer template constexpr bool is_same_ptr() noexcept { -#ifdef _MSC_VER - return true; -#else if constexpr (std::is_void_v || std::is_void_v || std::is_same_v) { return true; } else if constexpr (std::is_convertible_v) { - constexpr auto u = std::addressof(sample); - constexpr volatile void* x = u; - return static_cast(u) == x; + return is_same_ptr_test(); } else if constexpr (std::is_convertible_v) { - constexpr auto t = std::addressof(sample); - constexpr volatile void* x = t; - return static_cast(t) == x; + return is_same_ptr_test(); } - else - { - return false; - } -#endif + + return !std::is_class_v && !std::is_class_v && !std::is_union_v && !std::is_union_v; } template constexpr bool is_same_ptr_cast_v = std::is_convertible_v && is_same_ptr(); -#ifndef _MSC_VER -#pragma GCC diagnostic pop -#endif - template class single_ptr;