mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-05 17:30:27 +00:00
Fix shared_ptr_compatible
A shared_ptr<void> is not anonymous, it's just a wrapped void*.
This commit is contained in:
parent
709cc85d96
commit
47e4f60cf1
2 changed files with 18 additions and 13 deletions
|
@ -154,8 +154,8 @@ class shared_emplace : public shared_ref
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename U>
|
template <typename T, typename U>
|
||||||
concept shared_ptr_convertible = is_convertible_v<U, T> || is_void_v<T>;
|
concept shared_ptr_compatible = is_convertible_v<U*, T*>;
|
||||||
|
|
||||||
} // namespace __
|
} // namespace __
|
||||||
|
|
||||||
|
@ -175,15 +175,15 @@ class shared_ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
requires is_convertible_v<U, T>
|
requires __::shared_ptr_compatible<T, U>
|
||||||
explicit shared_ptr(U* const p) : shared_ptr(p, default_delete<U>())
|
explicit shared_ptr(U* const p) : shared_ptr(p, default_delete<U>())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U, typename D>
|
template<typename U, typename D>
|
||||||
requires is_convertible_v<U, T>
|
requires __::shared_ptr_compatible<T, U>
|
||||||
shared_ptr(U* const p, D d)
|
shared_ptr(U* const p, D d)
|
||||||
: p(p), rc(__::shared_pointer<T, D>::make(p, move(d)))
|
: p(p), rc(__::shared_pointer<U, D>::make(p, move(d)))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ class shared_ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
requires __::shared_ptr_convertible<T, U>
|
requires __::shared_ptr_compatible<T, U>
|
||||||
shared_ptr(const shared_ptr<U>& r) noexcept : p(r.p), rc(r.rc)
|
shared_ptr(const shared_ptr<U>& r) noexcept : p(r.p), rc(r.rc)
|
||||||
{
|
{
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@ -211,7 +211,7 @@ class shared_ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
requires __::shared_ptr_convertible<T, U>
|
requires __::shared_ptr_compatible<T, U>
|
||||||
shared_ptr(shared_ptr<U>&& r) noexcept : p(r.p), rc(r.rc)
|
shared_ptr(shared_ptr<U>&& r) noexcept : p(r.p), rc(r.rc)
|
||||||
{
|
{
|
||||||
r.p = nullptr;
|
r.p = nullptr;
|
||||||
|
@ -231,7 +231,7 @@ class shared_ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
requires is_convertible_v<U, T>
|
requires __::shared_ptr_compatible<T, U>
|
||||||
explicit shared_ptr(const weak_ptr<U>& r) : p(r.p), rc(r.rc)
|
explicit shared_ptr(const weak_ptr<U>& r) : p(r.p), rc(r.rc)
|
||||||
{
|
{
|
||||||
if (r.expired()) {
|
if (r.expired()) {
|
||||||
|
@ -241,7 +241,7 @@ class shared_ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U, typename D>
|
template<typename U, typename D>
|
||||||
requires is_convertible_v<U, T>
|
requires __::shared_ptr_compatible<T, U>
|
||||||
shared_ptr(unique_ptr<U, D>&& r)
|
shared_ptr(unique_ptr<U, D>&& r)
|
||||||
: p(r.p), rc(__::shared_pointer<U, D>::make(move(r)))
|
: p(r.p), rc(__::shared_pointer<U, D>::make(move(r)))
|
||||||
{
|
{
|
||||||
|
@ -260,7 +260,7 @@ class shared_ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
requires __::shared_ptr_convertible<T, U>
|
requires __::shared_ptr_compatible<T, U>
|
||||||
shared_ptr& operator=(shared_ptr<U> r) noexcept
|
shared_ptr& operator=(shared_ptr<U> r) noexcept
|
||||||
{
|
{
|
||||||
shared_ptr<T>(move(r)).swap(*this);
|
shared_ptr<T>(move(r)).swap(*this);
|
||||||
|
@ -277,14 +277,14 @@ class shared_ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
requires is_convertible_v<U, T>
|
requires __::shared_ptr_compatible<T, U>
|
||||||
void reset(U* const p2)
|
void reset(U* const p2)
|
||||||
{
|
{
|
||||||
shared_ptr<T>(p2).swap(*this);
|
shared_ptr<T>(p2).swap(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U, typename D>
|
template<typename U, typename D>
|
||||||
requires is_convertible_v<U, T>
|
requires __::shared_ptr_compatible<T, U>
|
||||||
void reset(U* const p2, D d)
|
void reset(U* const p2, D d)
|
||||||
{
|
{
|
||||||
shared_ptr<T>(p2, d).swap(*this);
|
shared_ptr<T>(p2, d).swap(*this);
|
||||||
|
@ -362,7 +362,7 @@ class weak_ptr
|
||||||
constexpr weak_ptr() noexcept = default;
|
constexpr weak_ptr() noexcept = default;
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
requires is_convertible_v<U, T>
|
requires __::shared_ptr_compatible<T, U>
|
||||||
weak_ptr(const shared_ptr<U>& r) noexcept : p(r.p), rc(r.rc)
|
weak_ptr(const shared_ptr<U>& r) noexcept : p(r.p), rc(r.rc)
|
||||||
{
|
{
|
||||||
if (rc)
|
if (rc)
|
||||||
|
|
|
@ -140,6 +140,11 @@ main()
|
||||||
shared_ptr<void> y(x);
|
shared_ptr<void> y(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// You can also create a shared pointer to void in the first place.
|
||||||
|
shared_ptr<void> x(new int);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// You can take a shared pointer to a subobject, and it will free the
|
// You can take a shared pointer to a subobject, and it will free the
|
||||||
// base object.
|
// base object.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue