mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-12 01:38:37 +12:00
shared_ptr.hpp: don't use fake objects
This lifts the limitation for casting with abstract classes. Use new C++20 feature (constexpr allocator) to test viability. Add SamePtr concept to types.hpp
This commit is contained in:
parent
eec9578619
commit
f5e529db61
4 changed files with 130 additions and 149 deletions
|
@ -9,6 +9,7 @@
|
|||
#include <array>
|
||||
#include <tuple>
|
||||
#include <compare>
|
||||
#include <memory>
|
||||
#include <bit>
|
||||
|
||||
using std::chrono::steady_clock;
|
||||
|
@ -1017,3 +1018,55 @@ concept PtrCastable = requires(const volatile X* x, const volatile Y* y)
|
|||
static_cast<const volatile Y*>(x);
|
||||
static_cast<const volatile X*>(y);
|
||||
};
|
||||
|
||||
template <typename X, typename Y> requires PtrCastable<X, Y>
|
||||
constexpr bool is_same_ptr()
|
||||
{
|
||||
if constexpr (std::is_void_v<X> || std::is_void_v<Y> || std::is_same_v<std::remove_cv_t<X>, std::remove_cv_t<Y>>)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if constexpr (sizeof(X) == sizeof(Y))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (std::is_constant_evaluated())
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if constexpr (sizeof(X) < sizeof(Y))
|
||||
{
|
||||
std::allocator<Y> a{};
|
||||
Y* ptr = a.allocate(1);
|
||||
result = static_cast<X*>(ptr) == static_cast<void*>(ptr);
|
||||
a.deallocate(ptr, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::allocator<X> a{};
|
||||
X* ptr = a.allocate(1);
|
||||
result = static_cast<Y*>(ptr) == static_cast<void*>(ptr);
|
||||
a.deallocate(ptr, 1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::aligned_union_t<0, X, Y> s;
|
||||
Y* ptr = reinterpret_cast<Y*>(&s);
|
||||
return static_cast<X*>(ptr) == static_cast<void*>(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename X, typename Y> requires PtrCastable<X, Y>
|
||||
constexpr bool is_same_ptr(const volatile Y* ptr)
|
||||
{
|
||||
return static_cast<const volatile X*>(ptr) == static_cast<const volatile void*>(ptr);
|
||||
}
|
||||
|
||||
template <typename X, typename Y>
|
||||
concept PtrSame = (is_same_ptr<X, Y>());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue