mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-03 08:20:28 +00:00
Basics of make_shared with anonymous union
This commit is contained in:
parent
0b710a112d
commit
da5817816d
2 changed files with 63 additions and 0 deletions
|
@ -2,6 +2,7 @@
|
|||
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
|
||||
#ifndef COSMOPOLITAN_CTL_SHARED_PTR_H_
|
||||
#define COSMOPOLITAN_CTL_SHARED_PTR_H_
|
||||
#include "new.h"
|
||||
#include "unique_ptr.h"
|
||||
|
||||
namespace ctl {
|
||||
|
@ -72,6 +73,39 @@ struct shared_pointer : shared_control
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct shared_emplace : shared_control
|
||||
{
|
||||
union {
|
||||
T t;
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
void construct(Args&&... args) {
|
||||
::new (&t) T(ctl::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
static unique_ptr<shared_emplace> make_unique()
|
||||
{
|
||||
return new shared_emplace();
|
||||
}
|
||||
|
||||
private:
|
||||
explicit constexpr shared_emplace() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
void on_zero_shared() noexcept override
|
||||
{
|
||||
t.~T();
|
||||
}
|
||||
|
||||
void on_zero_weak() noexcept override
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __
|
||||
|
||||
struct bad_weak_ptr : ctl::exception
|
||||
|
@ -203,10 +237,28 @@ class shared_ptr
|
|||
// TODO(mrdomino): owner_before(weak_ptr const&)
|
||||
|
||||
private:
|
||||
constexpr shared_ptr(T* const p, __::shared_control* rc) noexcept
|
||||
: p(p), rc(rc)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename U, typename... Args>
|
||||
friend shared_ptr<U> make_shared(Args&&... args);
|
||||
|
||||
T* p;
|
||||
__::shared_control* rc;
|
||||
};
|
||||
|
||||
template <typename T, typename... Args>
|
||||
shared_ptr<T> make_shared(Args&&... args)
|
||||
{
|
||||
auto rc = __::shared_emplace<T>::make_unique();
|
||||
rc->construct(ctl::forward<Args>(args)...);
|
||||
auto r = shared_ptr<T>(&rc->t, rc.get());
|
||||
rc.release();
|
||||
return r;
|
||||
}
|
||||
|
||||
// TODO(mrdomino): non-member functions (make_shared et al)
|
||||
// TODO(mrdomino): weak_ptr
|
||||
|
||||
|
|
|
@ -24,6 +24,11 @@
|
|||
template<typename T>
|
||||
using Ptr = ctl::shared_ptr<T>;
|
||||
|
||||
template <typename T, typename... Args>
|
||||
Ptr<T> Mk(Args&&... args) {
|
||||
return ctl::make_shared<T>(ctl::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
#undef ctl
|
||||
|
||||
int
|
||||
|
@ -62,6 +67,12 @@ main()
|
|||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
auto x = Mk<int>(5);
|
||||
if (x.use_count() != 1)
|
||||
return 8;
|
||||
}
|
||||
|
||||
// TODO(mrdomino): exercise more of API
|
||||
// TODO(mrdomino): threading stress-test
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue