mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-03 16:30:29 +00:00
Add bad_weak_ptr case
This commit is contained in:
parent
38f0504429
commit
f6fc17d2e5
2 changed files with 46 additions and 1 deletions
|
@ -4,6 +4,7 @@
|
|||
#define CTL_SHARED_PTR_H_
|
||||
|
||||
#include "conditional.h"
|
||||
#include "exception.h"
|
||||
#include "is_convertible.h"
|
||||
#include "is_void.h"
|
||||
#include "remove_extent.h"
|
||||
|
@ -11,6 +12,15 @@
|
|||
|
||||
namespace ctl {
|
||||
|
||||
class bad_weak_ptr : public exception
|
||||
{
|
||||
public:
|
||||
const char* what() const noexcept override
|
||||
{
|
||||
return "ctl::bad_weak_ptr";
|
||||
}
|
||||
};
|
||||
|
||||
namespace __ {
|
||||
|
||||
static inline __attribute__((always_inline)) void
|
||||
|
@ -217,8 +227,12 @@ class shared_ptr
|
|||
|
||||
template<typename U>
|
||||
requires is_convertible_v<U, T>
|
||||
explicit shared_ptr(const weak_ptr<U>& r) : shared_ptr(r.lock())
|
||||
explicit shared_ptr(const weak_ptr<U>& r) : p(r.p), rc(r.rc)
|
||||
{
|
||||
if (r.expired()) {
|
||||
throw bad_weak_ptr();
|
||||
}
|
||||
rc->keep_shared();
|
||||
}
|
||||
|
||||
// TODO(mrdomino): blocked on ctl::ref
|
||||
|
@ -408,6 +422,9 @@ class weak_ptr
|
|||
}
|
||||
|
||||
private:
|
||||
template<typename U>
|
||||
friend class shared_ptr;
|
||||
|
||||
element_type* p = nullptr;
|
||||
__::shared_ref* rc = nullptr;
|
||||
};
|
||||
|
|
|
@ -36,6 +36,8 @@ make_shared(Args&&... args)
|
|||
return ctl::make_shared<T, Args...>(ctl::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
using bad_weak_ptr = ctl::bad_weak_ptr;
|
||||
|
||||
#undef ctl
|
||||
|
||||
static int g = 0;
|
||||
|
@ -215,6 +217,32 @@ main()
|
|||
return 20;
|
||||
}
|
||||
|
||||
{
|
||||
// Expired weak pointers lock to nullptr, and throw when promoted to
|
||||
// shared pointer by constructor.
|
||||
auto x = make_shared<int>();
|
||||
weak_ptr<int> y(x);
|
||||
x.reset();
|
||||
if (y.lock())
|
||||
return 21;
|
||||
int caught = 0;
|
||||
try {
|
||||
shared_ptr<int> z(y);
|
||||
} catch (bad_weak_ptr& e) {
|
||||
caught = 1;
|
||||
}
|
||||
if (!caught)
|
||||
return 22;
|
||||
}
|
||||
|
||||
{
|
||||
// nullptr is always expired.
|
||||
shared_ptr<int> x(nullptr);
|
||||
weak_ptr<int> y(x);
|
||||
if (!y.expired())
|
||||
return 23;
|
||||
}
|
||||
|
||||
// TODO(mrdomino): exercise threads / races. The reference count should be
|
||||
// atomically maintained.
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue