mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-16 17:43:11 +00:00
shared_ptr.hpp: improve is_same_ptr<> trait
Don't always return true on MSVC.
This commit is contained in:
parent
02febd3f65
commit
94c62b1eec
@ -6,55 +6,58 @@
|
|||||||
|
|
||||||
namespace stx
|
namespace stx
|
||||||
{
|
{
|
||||||
#ifndef _MSC_VER
|
namespace detail
|
||||||
#pragma GCC diagnostic push
|
{
|
||||||
#ifdef __clang__
|
template <typename T>
|
||||||
#pragma GCC diagnostic ignored "-Wundefined-var-template"
|
union fake_t
|
||||||
#pragma GCC diagnostic ignored "-Wundefined-internal"
|
{
|
||||||
#endif
|
char dummy;
|
||||||
#endif
|
T data;
|
||||||
|
|
||||||
// Not defined anywhere (and produces a useless warning)
|
fake_t() noexcept {}
|
||||||
template <typename X>
|
~fake_t() {}
|
||||||
extern X sample;
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static const fake_t<std::remove_cv_t<T>> sample{};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename X, typename Y>
|
||||||
|
constexpr bool is_same_ptr_test(const volatile Y*, ...)
|
||||||
|
{
|
||||||
|
// Can't sample abstract class
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename X, typename Y, std::enable_if_t<!std::is_abstract_v<Y>, int> = 0>
|
||||||
|
constexpr bool is_same_ptr_test(const volatile Y* ptr = std::addressof(detail::sample<Y>.data))
|
||||||
|
{
|
||||||
|
return static_cast<const volatile X*>(ptr) == static_cast<const volatile void*>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
// Checks whether the cast between two types is the same pointer
|
// Checks whether the cast between two types is the same pointer
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
constexpr bool is_same_ptr() noexcept
|
constexpr bool is_same_ptr() noexcept
|
||||||
{
|
{
|
||||||
#ifdef _MSC_VER
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
if constexpr (std::is_void_v<T> || std::is_void_v<U> || std::is_same_v<T, U>)
|
if constexpr (std::is_void_v<T> || std::is_void_v<U> || std::is_same_v<T, U>)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if constexpr (std::is_convertible_v<U*, T*>)
|
else if constexpr (std::is_convertible_v<U*, T*>)
|
||||||
{
|
{
|
||||||
constexpr auto u = std::addressof(sample<U>);
|
return is_same_ptr_test<T, U>();
|
||||||
constexpr volatile void* x = u;
|
|
||||||
return static_cast<T*>(u) == x;
|
|
||||||
}
|
}
|
||||||
else if constexpr (std::is_convertible_v<T*, U*>)
|
else if constexpr (std::is_convertible_v<T*, U*>)
|
||||||
{
|
{
|
||||||
constexpr auto t = std::addressof(sample<T>);
|
return is_same_ptr_test<U, T>();
|
||||||
constexpr volatile void* x = t;
|
|
||||||
return static_cast<U*>(t) == x;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
return !std::is_class_v<T> && !std::is_class_v<U> && !std::is_union_v<T> && !std::is_union_v<U>;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
constexpr bool is_same_ptr_cast_v = std::is_convertible_v<U*, T*> && is_same_ptr<T, U>();
|
constexpr bool is_same_ptr_cast_v = std::is_convertible_v<U*, T*> && is_same_ptr<T, U>();
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class single_ptr;
|
class single_ptr;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user